在TypeScript中使用元组(类型推断)

时间:2018-02-08 13:39:06

标签: typescript

鉴于这个有点人为的例子:

['List', 'Of', 'Names']
        .map((name, index) => [name, index % 2])
        .map(([name, num]) => );

为什么类型string | number的最后一行中的name和num显然被推断为字符串和数字的数组,并且如果有一种方法可以使用类型推断,那么你们中的任何一个都知道这个名称是一个字符串num是一个数字?

2 个答案:

答案 0 :(得分:4)

对于数组文字,类型推断不会推断元组,它会推断数组,所以

var foo = ["", 0]; // foo is Array<string | number> not [string, number]

我还没有找到关于此的文档,但pull request添加对元组的支持在声明它们时从不使用推理,我猜这是故意的。

在您的情况下,您可以指定类型参数:

['List', 'Of', 'Names']
        .map<[string, number]>((name, index) => [name, index % 2])
        .map(([name, num]) => name + "");

2.9及以下解决方案

如果这是一个常见的问题,请创建一个元组助手函数:

function tuple<T1, T2, T3, T4, T5>(data: [T1, T2, T3, T4, T5]) : typeof data
function tuple<T1, T2, T3, T4>(data: [T1, T2, T3, T4]) : typeof data
function tuple<T1, T2, T3>(data: [T1, T2, T3]) : typeof data
function tuple<T1, T2>(data: [T1, T2]) : typeof data
function tuple(data: Array<any>){
    return data;
}

['List', 'Of', 'Names']
        .map((name, index) => tuple([name, index % 2]))
        .map(([name, num]) => name + "");

3.0解决方案

由于我发布了原始答案,打字稿已经改进了它的推断,能够推断出其余参数的元组类型。有关详细信息,请参阅PR。使用此功能,我们可以编写tuple函数的较短版本:

function tuple<T extends any[]> (...data: T){
    return data;
}

['List', 'Of', 'Names']
        .map((name, index) => tuple(name, index % 2))
        .map(([name, num]) => name + "");

答案 1 :(得分:2)

您可以使用const assertion

['List', 'Of', 'Names']
    .map((name, index) => [name, index % 2] as const) // insert `as const` here
    .map(([name, num]) => { }); // name: string, num: number

看看playground sample