Reputation: 1115
Might be a bad question or not even possible but I've been banging my head against it for awhile and cant figure it out. Thanks in advance!
The T generic creates a join type:
const arrayToArray = <T>(values: T[]) => values;
When I use the function:
const result = arrayToArray([1, 'hi', 3]);
It creates the type:
const result: (string | number)[]
I'm looking for it to create:
const result: [number, string, number]
I'm hoping for 'one'
and 'three'
to return a type error because they aren't numbers.
const useResultType: typeof result = ['one', 'two', 'three'];
Upvotes: 2
Views: 245
Reputation: 249716
You want to get tuples inferred from the array literal, there are two ways to convince the compiler to do this:
Using tuples in rest parameters. This removed the array literal from the call:
const arrayToArray = <T extends any[]>(...values: T) => values;
const result = arrayToArray(1, 'hi', 3); //[number, string, number]
Using an union of tuple and array constraint to hint to the compiler you want a union. This preserves passing the parameter as an array:
const arrayToArray = <T extends [any] | any[]>(values: T) => values;
const result = arrayToArray([1, 'hi', 3]); // [number, string, number]
Or if you want a readonly tuple in 3.4 (unreleased yet) you can directly use an as const
assertion:
const result = [1, 'hi', 3] as const; // readonly [number, string, number]
Upvotes: 4