首页 > 解决方案 > 防止 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>那么相应的函数编译得很好,但显然另一个函数没有。

问题是它JaggedElementTypeElementType.

如何防止这些重叠?

标签: typescript

解决方案


经过几个小时的摸索(在我要点击这个问题的发布按钮之前)我想通了,所以我想我会写下我自己的答案。

诀窍是,ElementType<T>检测是否Textends JaggedArray<T>,如果是,它不是ElementType. 我们通过使用never关键字来做到这一点。

type ElementType<T> = 
    T extends JaggedArray<T> ? never : 
    T extends Array<infer U> ? U : 
    T;

推荐阅读