打字稿:“关注”条件类型

时间:2020-03-13 12:45:19

标签: typescript

Typescript是否可以推断a: a b c d 0 NaN 1.0 2.0 3 1 4.0 NaN NaN 7 2 8.0 9.0 10.0 11 3 NaN NaN NaN 15 b: a b c d 0 NaN 1.0 2.0 3 1 5.0 NaN NaN 3 2 5.0 1.0 2.0 3 3 NaN NaN NaN 3 sum: 0 12.0 1 19.0 2 49.0 3 18.0 dtype: float64 也属于b类型?如果U extends Foo ? string : number的类型为a,则在true分支中,将数字添加到字符串将导致字符串。在false分支中,将数字添加到数字将最终成为数字。因此,我希望U extends Foo ? string : number的类型也可以推断为b。还是一个错误的假设?

运行下面的代码段时,出现以下错误:

运算符'+'不能应用于类型'U extended Foo吗?字符串:数字”和“数字”。(2365)

U extends Foo ? string : number

Playground Link

2 个答案:

答案 0 :(得分:0)

此问题与+运算符在TS中的严格行为有关。在结果可能超过主要类型+或主要类型string的情况下,TS绝对不允许使用number。函数foo使用+的方式是,结果类型是并集string | number,因为函数是多态的,并且参数x扩展了Foo那么如果没有string,我们将得到number

f级别上显示的条件类型不会被评估为foo中的最终类型,因为在该级别上我们有类型变量U,所以没有。如果将像以下示例中那样明确给出类型,则会将其评估为特定类型:

// types provided directly
const x =  f(1) // number
const y = f({propA: true, propB: false}) // string

function inside<U>(a:U) {
  const x =  f(a) // T extends Foo ? string : number // not evaluated
  return x + 1; // error
}

function insideButExactBranch<U extends Foo>(a:U) {
  const x =  f(a)
  return x + 1; // ok no error
}

foo中,我们仍然使用未知的U,这就是为什么认为f的结果是任何可能的原因,这意味着-string | number。如果是这样的话,+就无法编译。

换句话说,TS无法评估f函数的结果,因此它从条件类型中获取所有可能的返回类型,这意味着并集string | number。有关为何在TS中限制使用+的更多信息-Why TypeScript restricts + operator

答案 1 :(得分:-1)

Typescript在这里报告错误不是因为Javascript代码在运行时失败,而是因为根据类型注释,该代码有时执行字符串连接,而有时进行算术运算,这通常意味着程序员犯了一个错误。 / p>

在编写+时,您几乎总是希望要么意味着字符串连接,要么就希望它意味着算术,但是很少打算同时意味着这两种含义。因此,这是警告代码的错误,它可能是错误的。

如果您确实想要+有时会进行字符串连接并且有时会进行算术运算,则可以在该行之前添加一个@ts-ignore注释。这类似于Java中的@SuppressWarnings;您是在告诉编译器不要警告您通常表示错误的内容,因为在这种情况下 并不是错误,并且您不需要编译器就此警告您。

function foo<U>(x: U, d: number) {
  const a = f(x);
  // @ts-ignore
  const b = a + 2;
}