【问题标题】:Typescript Error Argument of type 'string | number' is not assignable to parameter of type 'never''string | 类型的 Typescript 错误参数number' 不可分配给“从不”类型的参数
【发布时间】:2020-11-10 17:03:42
【问题描述】:

我正在使用 Typescript 编写一段代码,并遇到了以下问题,我无法理解为什么会发生这种情况。

以下代码块在编译时触发Argument of type 'string | number' is not assignable to parameter of type 'never' 错误。

interface A {
    x: number | string
}

const a1: A[] = [{x: 1}, {x: 'a'}]
const b: number[] | string[] = ['a', 'b']

const a2 = a1.filter(a => b.includes(a.x))

但是;如果我在声明/分配b 时使用(number | string)[],它可以正常工作。

我检查了includes (Array<T>.includes(searchElement: never, ...) 的定义文件,但这也没有意义,因为我认为通用的T 将包含number[] | string[]

如果有人能阐明为什么Array<T> 不涵盖number[] | string[] 而是涵盖(number | string)[],我将不胜感激。

【问题讨论】:

  • number[] | string[] 是所有数字的数组或所有字符串的数组。 (number | string)[] 是一个元素数组,每个元素可以是数字或字符串。任何满足第一个定义的数组都会满足第二个,但反之则不然。
  • @jonrsharpe 感谢您的回复。看来我在代码块中打错了。对于那个很抱歉。问题和代码现在应该更有意义了。那么a.x 不应该与b 的每个元素相比较吗?因为它不像单个 stringnumber 比较,其结果总是错误的。

标签: typescript generics types


【解决方案1】:

您为b 设置的类型是number[] | string[]。这意味着它的类型将是或者一个数字数组(number[]一个字符串数组(string[])——这完全取决于你初始化的数据变量。

当你这样做时:

const b: number[] | string[] = ['a', 'b'];

您实际上将其类型设置为string[] - 这个变量b 现在与数字无关,只是一个字符串数组。

然后你继续做:

const a2 = a1.filter(a => b.includes(a.x));

因此,对于a1 的每个值(可能是stringnumber),您检查它是否存在于数组b 中。如上所述,b 是字符串数组only。而且你不能将number | string 传递给includes(),对于这个数组,它只需要一个string 参数(这个数组是Array<string>)。因此编译器错误。


现在,对于您建议的另一种情况:

const b: (number | string)[] = ['a', 'b'];

这定义了一个number | string 类型的数组,也就是说,它的每个元素都可以是不同的类型——numberstring。所以你可以有,例如:

const b: (number | string)[] = [1, 'b'];

碰巧在您的定义中,您的所有元素(其中两个)都是同一类型 - string

现在当您拨打includes() 时,情况就大不相同了。由于您的数组现在可以同时保存数字和字符串,include() 可以很高兴地使用这两种类型(这个数组是Array<number | string>),并且a.x 可以同时是这两种类型。

【讨论】:

    猜你喜欢
    • 2020-06-19
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 2022-11-12
    • 2021-07-02
    • 2019-09-07
    • 2020-04-04
    相关资源
    最近更新 更多