typescript - 防止 TypeScript 中的两种类型重叠
问题描述
我有以下声明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
文件中。
如果我只声明 and 之一ElementType<T>
,JaggedElementType<T>
那么相应的函数编译得很好,但显然另一个函数没有。
问题是它JaggedElementType
是ElementType
.
如何防止这些重叠?
解决方案
经过几个小时的摸索(就在我要点击这个问题的发布按钮之前)我想通了,所以我想我会写下我自己的答案。
诀窍是,ElementType<T>
检测是否T
extends JaggedArray<T>
,如果是,它不是ElementType
. 我们通过使用never
关键字来做到这一点。
type ElementType<T> =
T extends JaggedArray<T> ? never :
T extends Array<infer U> ? U :
T;
推荐阅读
- laravel - Laravel 错误 - 路线 [appraisal.appraisal_goals.manager_employee_goal/{id?}] 未定义
- reactjs - 刷新当前页面时如何重定向到另一个页面Reactjs
- perl - 我怎么知道钻石操作员是否移动到下一个文件?
- firebase - Firebase 实时数据库协议开销和 SSL 加密开销
- excel - 超级简单的 VLOOKUP 无法按预期检索值
- php - 为什么使用 CK 编辑器粘贴图表,当从页面查看时,它不能很好地显示?
- php - Angular:使用 api 数据填充的材料自动完成返回 JSON 值
- php - 如何优化此方法并避免 foreach 循环
- networking - 在我的 Ubuntu 17.04 系统中,为什么 /etc/resolv.conf fie 在重新启动时被覆盖?
- vb.net - 如何在 vb.net 中查找值为“新行”的 Excel 范围的地址?