【问题标题】:Type definition for a jagged array of type T and its array prototype extensionT 型锯齿数组的类型定义及其数组原型扩展
【发布时间】:2019-04-22 10:59:14
【问题描述】:

我正在尝试为我附加到 Array.prototype 的 JavaScript 函数编写 Typescript 定义文件。

Array.js

/**
 * Flattens the array recursively.
 *
 * @example
 * [1, [2, 3]].flat() // => [1, 2, 3]
 *
 * @example
 * [[1, [2, 3], [4, [5]]], 6].flat() // => [1, 2, 3, 4, 5, 6]
 */
Array.prototype.flat = function () {
    return this.reduce((arr, val) => Array.isArray(val) ? arr.concat(val.flat()) : arr.concat(val), []);
}

flat()Array<T|S> 上工作,其中SArray<T|S> 并返回Array<T>。也就是说,它具有递归定义,并且所有数组都符合定义,因为[1, 2, 3].flat() 将简单地返回原始数组的副本。

我是 TypeScript 的新手,但我的理解是,为了获得 TypeScript 定义文件(即 IntelliSense)的好处,方法定义必须在 interface Array<T> 内。如果是这种情况,有没有办法对T 的专用版本Array<T> 施加约束?

如果不是,我如何定义一个接口,该接口将为每个数组拾取并识别该数组何时适合递归定义?

【问题讨论】:

    标签: javascript typescript typescript-generics


    【解决方案1】:

    这不是一个完整的答案,但它确实让我们了解了大部分情况。这里是in the TypeScript Playground

    type JaggedArrayItem<T> = T | JaggedArray<T>;
    
    interface JaggedArray<T> extends Array<JaggedArrayItem<T>> { }
    
    type FlatArray<T> = T extends JaggedArrayItem<infer U> ? U[] : T;
    
    interface Array<T> {
      flat(this: JaggedArray<T>): FlatArray<T>;
    }
    
    Array.prototype.flat = function () {
      return this.reduce(
        (arr, val) => Array.isArray(val)
          ? arr.concat(val.flat())
          : arr.concat(val),
        []);
    };
    
    // Test
    
    const myRecursiveArray: JaggedArray<number> = [
      10,
      [9],
      [
        [8],
        [
          [7],
        ]
      ],
    ];
    
    const flattened: number[] = myRecursiveArray.flat();    
    const flattenedToo: (string | number)[] = [1, 'two'].flat();
    

    另见

    【讨论】:

    • 我们需要FlatArray&lt;T&gt; 有什么原因吗? flat()的签名不能只是flat(this: JaggedArray&lt;T&gt;): Array&lt;T&gt;;吗?我也不确定为什么我们需要显示联合类型的错误。 [ 1, 'foo' ].flat() 应该可以,不是吗?
    • @dfoverdx 关于用于显示错误的 TODO 项的要点。我把它放在那里是因为我虽然最初的问题想避免联合类型......我想我错了,所以我删除了那个 TODO 项目。
    • @dfoverdx 如果我们返回Array&lt;T&gt; 而不是FlatArray&lt;T&gt;,那么结果类型将不是T[]。例如,number[] 示例将在编译时返回此错误:Type 'JaggedArrayItem&lt;number&gt;[]' is not assignable to type 'number[]'. Type 'JaggedArrayItem&lt;number&gt;' is not assignable to type 'number'. Type 'JaggedArray&lt;number&gt;' is not assignable to type 'number'.
    猜你喜欢
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2022-07-12
    • 2014-09-25
    • 1970-01-01
    相关资源
    最近更新 更多