【问题标题】:Type inference with generic array in Typescript在 Typescript 中使用泛型数组进行类型推断
【发布时间】:2020-04-21 15:54:34
【问题描述】:
// Generic Constraints
class Car {
  print() {
    console.log('I am a car')
  }
}
class House {
  print() {
    console.log('I am a house')
  }
}

interface Printable {
  print(): void;
}

// tell Typescript that I promise the T type will satisfy the Printable interface
function printHousesOrCars<T extends Printable>(...arr: T[]): void {
  arr.forEach(item => item.print())
}

printHousesOrCars(1, 2, 3) // This line went wrong,I can understand
printHousesOrCars(new House(), new Car()) // this line Typescript infer T[] is Car[], I cannot understand, why shouldn't it be (House|Car)[]

我看不懂最后一行,如果我写了

const x = [new House(), new Car()] // Typescript 会将 x 推断为 (House|Car)[]

【问题讨论】:

  • 您的House 和Car 具有相同的structure,因此编译器将它们视为相同的类型。你应该distinguish them at the type level,比如添加不兼容的属性,比如manufacturer属性到Car和numBathrooms属性到House。
  • 如果你把你的函数改为:function printHousesOrCars&lt;T extends Printable[]&gt;(...arr: T): void { //etc... 呢?
  • @jcalz 谢谢,这真的很有帮助。是不是意味着使用泛型,TS不会将类型推断为联合类型,它必须是特定类型。
  • @flavio 不起作用兄弟,那么 T[] 是一个二维数组
  • @crazyones110 它不限于二维数组。数组的长度实际上取决于您如何调用该函数。如果你用 10 个参数调用它,它会推断出一个有 10 个元素的元组。 Look this playground code

标签: typescript generics type-inference typescript-generics


【解决方案1】:

Typescript 将以下行解释为 [House, Car] 类型的两个元素元组。

const x = [new House(), new Car()] // Typescript will infer x as (House|Car)[]

我知道这有点令人困惑,因为两者都使用相同的语法,即 [ 和 ]。

现在您可以稍微修改函数签名,以便产生我认为更正确的输入。

function printHousesOrCars<T extends Printable[]>(...arr: T): void {
  arr.forEach(item => item.print())
}

在调用站点上,上述内容将被解析为具有第一个参数House 和第二个参数Car 的函数。

printHousesOrCars(new House(), new Car()) // [House, Car]

Playground More on the rest parameters subject

我希望这是有道理的。 :)

【讨论】:

  • 你的意思是所有联合类型的数组都会被解释为元组?喜欢const y = [1, true, 'hello'] 。实际上,当光标悬停时,它是 [number, boolean, string] 元组而不是 (number|boolean|string)[] 。为了简单起见,Typescript 将 (number|boolean|string)[] 视为元组的符号?
猜你喜欢
  • 1970-01-01
  • 2020-09-09
  • 2019-09-17
  • 2016-12-05
  • 2021-05-13
  • 2020-07-23
  • 2017-10-04
  • 1970-01-01
  • 2018-01-18
相关资源
最近更新 更多