受保护的类型,仍然不可分配 [英] Guarded type, still not assignable

查看:30
本文介绍了受保护的类型,仍然不可分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的输出类型取决于输入类型.我用自定义保护保护输入,但它仍然不能分配给声明的输出:

My out type depends on the input type. I'm guarding the input with custom guard, but it's still not assignable to declared output:

type InputType<Sub extends SubType> = { a: Sub, b: string }
type SubType = Sub1 | Sub2
type Sub1 = { a: string }
type Sub2 = { a: string, b: string }
type OutputType<Sub extends SubType> =
  Sub extends Sub2 ?
    { c: string, d: string } :
    { c: string }

function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub> {
  if (hasSub2(mainType)) {
    return {c: '', d: ''};
  } else {
    return {c: ''};
  }
}

function hasSub2(a: InputType<SubType>): a is InputType<Sub2> {
  return 'b' in a.a;
}

这里的一个游乐场

推荐答案

当前的 TS 设计限制是函数返回表达式必须可分配给显式未解析的条件返回类型注释,缩小控制流并没有帮助(问题).

A current TS design limitation is that function return expressions must be assignable to the explicit unresolved conditional return type annotation, narrowing with the control flow doesn't help (issue).

{c: '', d: ''}{c: ''} 不可分配给未解析的条件返回类型 OutputType.您可以执行以下操作:

{c: '', d: ''} and {c: ''} in handle are not assignable to the unresolved conditional return type OutputType<Sub>. You can do the following:

  1. 投所有返回表达式<代码>输出类型<副> (样本)
  2. 创建一个单独的函数过载(样本)

替代方案 2 的实施

function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub>
function handle(mainType: InputType<SubType>): OutputType<SubType> {
  if ('b' in mainType.a) {
    return { c: '', d: '' };
  } else {
    return { c: '' };
  }
}

const sub1Res = handle({ a: { a: "aa" }, b: "b" }) // {c: string; }
const sub2Res = handle({ a: { a: "aa", b: "ab" }, b: "b" }) // { c: string; d: string; }

通过这种方式,函数的调用者获得正确的返回类型,并且函数体(被调用者或实现端)现在编译.

This way, the caller of the function gets the right return type and also the body of the function (callee or implementation side) compiles now.

这篇关于受保护的类型,仍然不可分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆