【问题标题】:TypeScript type definition for flatten function扁平化函数的 TypeScript 类型定义
【发布时间】:2020-06-04 01:34:33
【问题描述】:

我有简单的flatten 功能。这个想法是它可以采用字符串数组或字符串数​​组数组,并且总是只返回 1 级字符串数组。例如:

flatten(['a', ['b']]) // returns ['a', 'b']
flatten(['a', 'b']) // returns ['a', 'b']

这里是这个函数的实现

function flatten(arr: ReadonlyArray<string | string[]>): string[] {
   return [].concat(...arr);
}

我收到以下 TypeScript 编译器错误:

  error TS2769: No overload matches this call.
    Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
      Argument of type 'string | string[]' is not assignable to parameter of type 'ConcatArray<never>'.
        Type 'string' is not assignable to type 'ConcatArray<never>'.
    Overload 2 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
      Argument of type 'string | string[]' is not assignable to parameter of type 'ConcatArray<never>'.
        Type 'string' is not assignable to type 'ConcatArray<never>'.

  105   return [].concat(...arr);
                        ~~~~~~

如何定义此flatten 函数的输入和输出类型?我想避免使用any 类型。

【问题讨论】:

    标签: typescript types typescript-typings


    【解决方案1】:

    我认为编译器无法确定 [] 值应该是什么数组类型。这里最简单的解决方法是告诉它这是一个string[] 和一个type assertion

    function flatten(arr: ReadonlyArray<string | string[]>): string[] {
       return ([] as string[]).concat(...arr);
    }
    

    希望有所帮助;祝你好运!

    Playground link to code

    【讨论】:

      【解决方案2】:

      您必须指定返回值的类型,在本例中为字符串数组。

      function flatten(arr: ReadonlyArray<string | string[]>): string[] {
          const output: string[] = [];
          return output.concat(...arr);
      }
      

      【讨论】:

        【解决方案3】:

        如果有人正在寻找任意深度和任意类型的扁平化数组,这是一个解决方案:

        type ExtractLeafTypes<T> = T extends ReadonlyArray<infer U> ? ExtractLeafTypes<U> : T
        function deepFlatten<T extends ReadonlyArray<any>>(arr: T): Array<ExtractLeafTypes<T>> {
            return arr.reduce((acc, n) => acc.concat(Array.isArray(n) ? deepFlatten(n) : [n]) , [])
        }
        
        const numbers = [1, [2], [[3]], [[[[4]]]]]
        const flatNumbers = deepFlatten(numbers) // : number[]
        const mixed = [1, ['a', ['b'], [[[[[[['c']]]]]]]], [2, [3, [[[[[[[[[[4]]]]]]]]]]]]]
        const flatMixed = deepFlatten(mixed) // : (number | string)[]
        const strict = [1, ['a', ['b'], [[[[[[['c']]]]]]]], [2, [3, [[[[[[[[[[4]]]]]]]]]]]]] as const
        const flatStrict = deepFlatten(strict) // :  (1 | "a" | "b" | "c" | 3 | 2 | 4)[]
        

        PLAYGROUND

        【讨论】:

          猜你喜欢
          • 2016-04-05
          • 1970-01-01
          • 2021-02-20
          • 1970-01-01
          • 2017-10-28
          • 2021-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多