Javascript 是否可以在TypeScript中对元组使用Array.prototype.map(),同时在返回类型中保留元组长度?

Javascript 是否可以在TypeScript中对元组使用Array.prototype.map(),同时在返回类型中保留元组长度?,javascript,arrays,typescript,types,tuples,Javascript,Arrays,Typescript,Types,Tuples,我希望如果在TypeScript中对长度为N的元组使用内置的map函数,那么返回类型也将是长度为N的元组(根据传递给map的函数,元素的类型可能不同)。相反,返回类型只是回调函数返回的任何类型的标准可变长度数组。元组的长度丢失。我写了一个自定义函数,可以实现我想要的功能,但我想知道是否有更好的方法可以实现。我正在努力提高我对打字脚本的理解。我在代码下面包含了一个TypeScript链接(使用相同的代码)。谢谢你的帮助 const nums = [1, 2, 3] as const; // re

我希望如果在TypeScript中对长度为N的元组使用内置的
map
函数,那么返回类型也将是长度为N的元组(根据传递给
map
的函数,元素的类型可能不同)。相反,返回类型只是回调函数返回的任何类型的标准可变长度数组。元组的长度丢失。我写了一个自定义函数,可以实现我想要的功能,但我想知道是否有更好的方法可以实现。我正在努力提高我对打字脚本的理解。我在代码下面包含了一个TypeScript链接(使用相同的代码)。谢谢你的帮助

const nums = [1, 2, 3] as const;

// result1 type is string[]
const result1 = nums.map((num) => num.toString());

// so this won't compile
const result2: [string, string, string] = nums.map((num) => num.toString());

// a type assertion would work, but I'd rather not use one...
const result3 = nums.map((num) => num.toString()) as [string, string, string];

// ...because this also compiles yet the type of result4 doesn't match its value
const result4 = nums.map((num) => num.toString()) as [string, boolean, number, symbol, string, number];

// result5 type is [string, string, string]
const result5 = map(nums, (num) => num.toString());

// custom map function that yields the correct return type when used on a tuple
function map<A extends readonly [...any[]], B>(values: A, func: (value: A[number]) => B): { [K in keyof A]: B } {
    return values.map(func) as unknown as { [K in keyof A]: B };
}

constnums=[1,2,3]作为常量;
//result1类型为string[]
const result1=nums.map((num)=>num.toString());
//所以这不会被编译
const result2:[string,string,string]=nums.map((num)=>num.toString());
//类型断言可以工作,但我不想使用类型断言。。。
const result3=nums.map((num)=>num.toString())为[string,string,string];
//…因为这也会编译,但result4的类型与其值不匹配
const result4=nums.map((num)=>num.toString())为[string,boolean,number,symbol,string,number];
//结果5类型为[string,string,string]
const result5=map(nums,(num)=>num.toString());
//自定义映射函数,用于元组时生成正确的返回类型
功能图

请尝试下一步:


类型A=只读[1,2,3]
常量nums:A=[1,2,3];
常量toStr=(num:T)=>num.toString()作为`${T}`
const result2=nums.map(toStr);//("3" | "1" | "2")[]
我认为这不是最好的解决方案,因为您仍然有('3'|'2'|'1')[],而不是('1'、'2'、'3')],但这是向前迈出的一步

我很高兴在这里看到其他解决办法。(非常有趣的问题)

仅适用于T.S 4.1

更新

可以创建您想要的类型:

//https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type/50375286#50375286
类型UnionToIntersection=(U扩展任何?(k:U)=>void:never)扩展(
k:我推断
)=>无效
? 我
:从不;
// https://github.com/microsoft/TypeScript/issues/13298#issuecomment-468114901
类型UnionToOvlds=UnionToIntersection<
你有吗?(f:U)=>无效:从不
>;
//https://github.com/microsoft/TypeScript/issues/13298#issuecomment-468114901
类型PopUnion=UnionToOvlds扩展(a:推断a)=>void?答:从来没有;
// https://stackoverflow.com/questions/53953814/typescript-check-if-a-type-is-a-union#comment-94748994
类型IsUnion=[T]扩展了[UnionToIntersection]?假:真;
// https://catchts.com/union-array
类型UnionToArray=IsUnion扩展为true
? 工会阵列
:[T,…A];
常量映射=(值:A)=>
(func:(值:A[number])=>T=>{
类型映射<
Arr扩展了数组,
结果扩展数组=[],
>=Arr扩展[]
? []
:Arr扩展[推断H]
?[…结果,T]
:Arr延伸[推断头部,…推断尾部]
?映射
:只读;
按映射返回(values.map(func))
}
常量arr=[1,2,3]作为常量;
类型Arr=类型Arr;
constresult2=map([1,2,3]作为const)(elem=>({elem}));
我不知道为什么,但在函数中声明类型并不是最好的主意。从那以后,我就可以在笔记本电脑上烧烤了

对于类型铸件,可以随意使用
映射的
类型util