For arrays literals type inference does not infer tuples, it infers arrays, so
var foo = ["", 0]; // foo is Array<string | number> not [string, number]
I have not found documentation on this but the pull request adding support for tuples never uses inference when declaring them, I'm guessing this is deliberate.
In your case you can specify the type parameter:
['List', 'Of', 'Names']
.map<[string, number]>((name, index) => [name, index % 2])
.map(([name, num]) => name + "");
2.9 and below solution
Or create a tuple helper function if this is a common issue for you:
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 Solution
Since I posted the original answer typescript has improved it's inference with the ability to infer tuple types for rest parameters. See PR for details. With this feature we can write a shorter version of the tuple
function :
function tuple<T extends any[]> (...data: T){
return data;
}
['List', 'Of', 'Names']
.map((name, index) => tuple(name, index % 2))
.map(([name, num]) => name + "");