TypeScript通用函数-为数组应用函数时出现“参数不可分配错误”

时间:2019-01-18 06:50:10

标签: typescript generics

说明

我想在TypeScript中定义一个泛型函数,以便它将转换应用于数组参数,然后返回相同类型的数组。 (使用的TypeScript版本:v3.24)

简化的代码段如下:

describe("generic functions", function () {
    it("should not give transpilation error", function () {
        // given
        function myFunction<T>(arr: T[]): T[] {
            // ...... apply some transformation to the array here
            return arr; // or return a copy of the array of same type
        }

        let arrays = [
            ["a"],
            [1]
        ]; // Just for demonstration purpose, the actual input has more varieties of types

        // These can be transpiled without error
        myFunction(["b"]);
        myFunction([2]);
        arrays.map(myFunction);

        // This gives transpilation error, see following for the detailed message
        arrays.map(arr => myFunction(arr));
    });
});

特别是,我不确定为什么仅当我将函数应用于混合类型数组并显式调用它时,TS编译器才能识别类型。

翻译错误消息是:

  

TS2345:“字符串[] |类型的参数不能将number []'分配给'string []'类型的参数。     类型'number []'不可分配给类型'string []'。       不能将“数字”类型分配给“字符串”类型。

类似的问题

  1. Assigning generics function to delegate in Typescript-但是我想保留通用签名,因为我希望我的功能更加灵活
  2. Typescript Generic type not assignable error-但是我的函数返回的是泛型类型。

(很抱歉,如果这与另一个问题重复,请告诉我-我曾尝试搜索但未能找到可以回答此问题的问题)

1 个答案:

答案 0 :(得分:1)

编译器在解开(string[] | number[])类型以推断类型参数时遇到麻烦。在这种情况下,显式传递type参数将起作用:

arrays.map(arr => myFunction<string | number>(arr));

这是编译器处理的情况之一:

(string | number)[][]

不同于:

(string[] | number[])[]

如果使用后者,则它将类型参数推断为string[],然后对number[]失败。

您可以使用类型保护来帮助编译器,但是这个示例确实是一个练习,我无法想象要在现实生活中使用它:

function isStringArray(arr: any[]): arr is string[] {
    return (typeof arr[0] === 'string');
}

arrays.map(arr => (isStringArray(arr)) ? myFunction(arr) : myFunction(arr));

即使以任何一种方式调用myFunction,它也可以在每种情况下将类型参数推断为string[]number[]