我在Array.ts
中有以下声明,它们充当Array<T>.flat()
和Array<T>.flatDeep()
的帮助程序类型和声明。
export {}
type ElementType<T> = T extends (infer U)[] ? U : T;
type JaggedArrayItem<T> = T | JaggedArray<T>;
type JaggedElementType<T> = T extends JaggedArray<infer U> ? U : T;
interface JaggedArray<T> extends Array<JaggedArrayItem<T>> { }
declare global {
interface Array<T> {
/**
* Flattens the array one level, removing empty elements. Does not flatten recursively.
*
* @example
* [1, [2, 3]].flat() // => [1, 2, 3]
*
* @example
* [[1, [2, 3], [4, [5]]], 6].flat() // => [1, 2, 3, 4, [5], 6]
*
* @example
* let arr = new Array(3);
* arr[0] = 1;
* arr[2] = undefined;
*
* arr.flat() // => [1, undefined]
*/
flat(): ElementType<T>[];
/**
* Flattens the array recursively. Removes empty elements.
*
* @example
* [1, [2, 3]].flatDeep() // => [1, 2, 3]
*
* @example
* [[1, [2, 3], [4, [5]]], 6].flatDeep() // => [1, 2, 3, 4, 5, 6]
*
* @example
* let arr = new Array(3);
* arr[0] = 1;
* arr[2] = undefined;
*
* arr.flatDeep() // => [1, undefined]
*/
flatDeep(this: JaggedArray<T>): JaggedElementType<T>[];
}
}
Array<T>.flat()
仅展平阵列的一个深度,而Array<T>.flatDeep()
展平整个物体。
[1, [2, [3]]].flat() // => [1, 2, [3]]
[1, [2, [3]]].flatDeep() // => [1, 2, 3]
但是,当我对此进行编译时,有时会出现错误:
返回类型注释会循环引用自身。
奇怪的是,我有时只会得到这个。有时它编译良好。但是,即使编译正常,此错误也会出现在生成的Array.d.ts
文件中。
如果我只声明ElementType<T>
和JaggedElementType<T>
中的一个,则相应的函数可以很好地编译,但是显然另一个函数则不能。
问题在于JaggedElementType
是ElementType
的超集。
如何防止它们重叠?
答案 0 :(得分:0)
经过几个小时的整理(并且在我要单击该问题的发布按钮之前,正确),我发现了这一点,所以我想写自己的答案。
诀窍是,在ElementType<T>
中检测T
是否扩展了JaggedArray<T>
,如果是,则它不是ElementType
。我们通过使用never
关键字来做到这一点。
type ElementType<T> =
T extends JaggedArray<T> ? never :
T extends Array<infer U> ? U :
T;