I have a custom type that distinguishes between tuples (exact length) and arrays. I'm looking to leverage this distinction to automatically infer parameter types:
type ANumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
type IsTuple<Type> = Type extends readonly unknown[] ? Type['length'] extends ANumber ? true : false : false;
function fn<T extends Record<keyof T, unknown>>() {
return function withConfig(config: {
[K in keyof T]: IsTuple<T[K]> extends true
? (...params: T[K]) => void
: (param: T[K]) => void
}) {};
}
fn<{ tupleType: [number, number], arrayType: number[] }>()({
tupleType: (one, two) => {},
arrayType: (arr) => {}
})
The function call executes successfully, and one
, two
, and arr
are correctly inferred. However, the line ? (...params: T[K]) => void
triggers an error:
A rest parameter must be of an array type
But wait... isn't a tuple technically an array type too? How can I guide the compiler to understand this distinction?