首页 > 解决方案 > Typescript函数数组类型检查

问题描述

代码很简单

// it is ok because type 'string' is assignable to type 'string | number'

const arr:Array<string|number> = []

arr.push('foo')


但我收到以下代码错误。

interface Fn<T> {
  (val: T): T
}


const fnArr:Fn<string|number>[] = []


const fn = (str:string)=>str

//error
fnArr.push(fn)

错误显示:

 Argument of type '(str: string) => string' is not assignable to parameter of type 'Fn<string | number>'.
 Types of parameters 'str' and 'val' are incompatible.
 Type 'string | number' is not assignable to type 'string'.
 Type 'number' is not assignable to type 'string'.(2345)

逻辑似乎相反。fnArr 被声明为一个数组,其元素是带有字符串或数字参数的函数,因此推送带有字符串参数的函数是有效的。我 'string' is assignable to type 'string | number',但为什么错误显示Type 'string | number' is not assignable to type 'string'.

TS 处理数组元素类型检查时的规则是什么?将元素类型分配给声明的数组类型或将声明的数组类型分配给元素类型?

编辑:

阅读@Aleksey 提到的文档后我仍然感到有些困惑。我是说功能

(val: string | number) => string | number

val有typestring或 type的参数number,我认为它比函数只有 type 的参数更大string。就像一个比喻。我认为 typenumber扩展了 type number | string。所以我认为上面的代码不应该有任何错误

相反,正如@Aleksey 所说,函数

(val: string | number) => string | number

可以处理 number 和 string 类型的参数,但是函数(val: string) => string不能处理 type 的参数number,我认为他是正确的。

所以我仍然感到困惑。

标签: typescript

解决方案


所以这里的实际问题是为什么

(val: string) => string

不可分配给

(val: string | number) => string | number

那是因为前者不能处理类型的参数number

要检查是否x可分配给y,我们首先查看参数列表。in 中的每个参数都x必须有对应y类型兼容的参数 in。

更多关于函数类型兼容性的信息在这里


因此,一种可能的解决方案是声明可以接受类型
(val: string) => string函数或类型函数的数组(val: number) => number

const fnArr: (Fn<string> | Fn<number>)[] = []

const fn = (str: string) => str

fnArr.push(fn) // is ok now

操场


推荐阅读