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

Posted

技术标签:

【中文标题】TypeScript 通用函数 - 为数组应用函数时出现“参数不可分配错误”【英文标题】:TypeScript Generic Function - "Argument not assignable error" when applying function for array 【发布时间】:2019-06-12 10:10:16 【问题描述】:

说明

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

sn-p简化代码如下:

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:'string[]| 类型的参数number[]' 不能分配给“string[]”类型的参数。 类型 'number[]' 不能分配给类型 'string[]'。 类型“数字”不可分配给类型“字符串”。

类似问题

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

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

【问题讨论】:

【参考方案1】:

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

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[]

【讨论】:

以上是关于TypeScript 通用函数 - 为数组应用函数时出现“参数不可分配错误”的主要内容,如果未能解决你的问题,请参考以下文章

使用 Array.map (TypeScript) 返回一个通用数组

返回函数的通用 TypeScript 类型,将 ReturnType 替换为返回函数的 ReturnType

Typescript - 为非常通用的功能定义接口[重复]

具有通用联合约束的 TypeScript 函数返回值

sequelize-typescript:模型中get()的通用方法

TypeScript 3 的通用 curry 函数