首页 > 解决方案 > 打字稿:“关注”条件类型

问题描述

Typescript 有什么方法可以推断出b也属于 typeU extends Foo ? string : number吗?如果a是类型,U extends Foo ? string : number那么在真正的分支中将数字添加到字符串将导致字符串。在 false 分支中,将一个数字添加到 number 最终将成为一个数字。因此,我希望类型b也可以推断为U extends Foo ? string : number. 或者这是一个错误的假设?

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

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

interface Foo {
  propA: boolean;
  propB: boolean;
}

declare function f<T>(x: T): T extends Foo ? string : number;

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

游乐场链接

标签: typescript

解决方案


该问题与+TS 中操作员的严格行为有关。TS 绝不允许+在结果可能超过主要类型string或主要类型的情况下使用number。函数以这样的方式foo使用+,结果类型是 union string | number,因为函数是多态的,如果参数x扩展Foo,那么我们将得到stringif not 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我们仍然使用 unknownU时,这就是为什么结果f被认为是任何可能的,这意味着 - string | number。如果是这样,+则无法编译。

换句话说 - TS 无法评估f函数的结果,因此它从条件类型中获取所有可能的返回类型,这意味着 union string | number。更多关于为什么使用+在 TS 中受到限制的更多信息 -为什么 TypeScript 限制 + 运算符


推荐阅读