我注意到TypeScript中的Array.concat
方法在语言的官方类型定义文件中定义了两次。下面是该方法的定义:
/**
* Combines two or more arrays.
* This method returns a new array without modifying any existing arrays.
* @param items Additional arrays and/or items to add to the end of the array.
*/
concat(...items: ConcatArray<T>[]): T[];
/**
* Combines two or more arrays.
* This method returns a new array without modifying any existing arrays.
* @param items Additional arrays and/or items to add to the end of the array.
*/
concat(...items: (T | ConcatArray<T>)[]): T[];
字符串
我很好奇为何要重复界定,以及两个定义是否有分别,请问有没有人可以解释为何会重复界定,以及如果有分别的话,可否澄清?
2条答案
按热度按时间1szpjjfi1#
我研究了这个问题,它看起来像是一个历史问题的遗留问题,与今天没有直接关系。在某个时候(TypeScript 2.0-ish),TypeScript对
Array.prototype.concat()
的声明有一个单一的调用签名来解释输入中的单个元素和数组(因为这表现得不同):字符串
但是当内部元素是元组类型时,这会产生一个问题,导致在microsoft/TypeScript#9901上的错误报告,其中
型
会失败,因为编译器将
[3, 4]
和[5, 6]
视为类型number[]
,而[7, 8]
是预期的[number, number]
。T | T[]
在面对元组时会使编译器感到困惑。他们决定修复方法是添加一个重载(实际上是“重新添加”一个重载,你可以自己在GitHub上研究完整的疯狂历史)在尝试处理混合数组之前,它首先尝试将输入视为单个数组类型。这在microsoft/TypeScript#9997中完成,导致这对签名:型
这解决了问题。
从那时起,发生了一些变化:
T[]
的用法更改为ReadonlyArray<T>
。T[] | ReadonlyArray<T>
。ConcatArray<T>
,它是T[] | Readonlyarray<T>
的超类型。这导致了当前的签名:
型
从历史的Angular 来看,这就是“原因”。从概念上讲,你应该只需要第二个调用签名,但第一个是为了解决一个bug而添加的。
问题是,即使你删除了第一个调用签名,这个bug似乎也不存在了:
型
我假设自TypeScript 2.0以来,一些元组处理发生了重大变化。因此,在这一点上,可能没有任何理由存在第一个调用签名。感兴趣的一方可能想提出一个GitHub问题,要求将其删除。这样的问题可能会受到欢迎,也可能不会受到欢迎;破坏
concat()
的稳定性可能会带来更多的麻烦,但这超出了所问问题的范围,所以我将就此结束。Playground链接到代码
fd3cxomn2#
Array.concat方法在TypeScript中没有定义两次;它只有一个定义。它是标准JavaScript Array原型的一部分,也可以在TypeScript中访问。
如果有重复的感觉,可能是因为TypeScript为JavaScript方法提供了类型注解,这些注解是TypeScript标准库声明的一部分。然而,Array.concat的实际实现是JavaScript运行时的一部分,TypeScript继承并扩展了这些类型。
要在TypeScript中使用Array.concat,您可能会看到如下类型注解:
字符串