I want to use a function that constructs an array as an argument, where each element may be a different type. The order of types is relevant and I need to preserve their order as a Tuple. Here is one way:
const create = <T>(spec: (...args: any[]) => T) => spec;
const result = create(() => ['a', 2, 'a'] as const);
type t = ReturnType<typeof result>; // t is ['a', 2, 'a']
However, this means the developer has to remember to add as const
every time they use create
.
In my use case, the order of types is always relevant and the function should always receive a Tuple.
Is there any way to force Typescript to always infer the Tuple from the return type without needing as const
?
You can hint to the compiler that a generic type argument should be inferred as a tuple type if you specify the constraint of it as [any] | any[]
.
const create = <T extends [any] | any[]>(spec: (...args: any[]) => T) => spec;
const result = create(() => ['a', 2, 'a']);
type t = ReturnType<typeof result>; // t is [string, number, string]
It doesn't seem possible to infer the literal constant such as ['a', 2, 'a']
.