【问题标题】:Conditional types issue in TypeScriptTypeScript 中的条件类型问题
【发布时间】:2021-02-03 07:19:43
【问题描述】:

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

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 playground link)

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

【问题讨论】:

  • 您的 BarValueType 别名在这里是多余的。你能提供一个removing them would not be trivial的例子吗?
  • @PatrickRoberts 不确定你的意思。你的例子没有失败。我的失败。所以你的例子是不同的。
  • “你的例子”(5分钟后无法修复错字)

标签: typescript conditional-types


【解决方案1】:

什么是错误

这是你得到的错误:

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&lt;T&gt;' is not assignable to type 'string'. Type 'number | boolean' is not assignable to type 'string'.,出现这个错误是完全合理的,我们在下面解释这个

说明

事实 1:

基于export type Bar&lt;T&gt; = T extends true ? boolean : number

  • 栏只能是booleannumber

事实 2:

基于type ValueType&lt;T&gt; = [T] extends [string] ? Value&lt;string&gt; : Value&lt;T&gt;;

  • 表示ValueType可以是Value&lt;string&gt;

事实 3:

基于foo&lt;T&gt;(vt: ValueType&lt;Bar&lt;T&gt;&gt;, v: Bar&lt;T&gt;)

  • 使用事实 2,表示 means vt.set can take string

分辨率

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

【讨论】:

  • 我不明白为什么vt.set 可以接受string。因为Bar&lt;T&gt; 只能是booleannumber。因此[number | boolean] extends [string] 为假。
猜你喜欢
  • 2018-09-24
  • 2020-10-14
  • 2020-03-29
  • 2018-10-20
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 2016-04-04
相关资源
最近更新 更多