我想在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 []'。 不能将“数字”类型分配给“字符串”类型。
(很抱歉,如果这与另一个问题重复,请告诉我-我曾尝试搜索但未能找到可以回答此问题的问题)
答案 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[]
。