首页 > 解决方案 > TypeScript 中的条件类型问题

问题描述

这是一个复杂代码的简化示例:

type ValueType<T> = [T] extends [string] ? Value<string> : Value<T>;

interface Value<T> {
    set(v: T): void
}

export type Bar<T> = T extends true ? boolean : number

function foo<T>(vt: ValueType<Bar<T>>, v: Bar<T>) {
    vt.set(v); <-- error here
}

最新的 TypeScript (v4.1.3) 在以下语句vt.set(v)中失败:

“Bar”类型的参数不能分配给“string & Bar”类型的参数。

TypeScript 游乐场链接

这种行为是记录在某处还是一个错误?

标签: typescriptconditional-types

解决方案


什么是错误

这是您收到的错误:

Argument of type 'Bar<T>' is not assignable to parameter of type 'string & Bar<T>'. 
  Type 'number | boolean' is not assignable to type 'string & Bar<T>'. Type 'number' is not assignable to type 'string & Bar<T>'. 
    Type 'number' is not assignable to type 'string'. 
       Type 'Bar<T>' is not assignable to type 'string'. Type 'number | boolean' is not assignable to type 'string'. 

所以根本原因是Type 'Bar<T>' is not assignable to type 'string'. Type 'number | boolean' is not assignable to type 'string'.,出现这个错误是非常有意义的,我们在下面解释

解释

事实1:

基于export type Bar<T> = T extends true ? boolean : number

  • 酒吧只能是booleannumber

事实2:

基于type ValueType<T> = [T] extends [string] ? Value<string> : Value<T>;

  • 意味着ValueType可以Value<string>

事实 3:

基于foo<T>(vt: ValueType<Bar<T>>, v: Bar<T>)

  • 使用事实 2,意味着means vt.set can take string

解析度

基于 Fact 1(只能是booleanor number)和 Fact 2(可以采用 a string),我们收到来自 TypeScript 的错误消息:Type 'number | boolean' is not assignable to type 'string'


推荐阅读