Reputation:
It makes sense that [number, number] | [number]
extends [number, ...number[]]
, but I'm wondering if there's a way to enforce the tuple length based on the first parameter so that the second tuple must use that same length.
function addVectors<T extends [number, ...number[]]>(v1: T, v2: T) {
// not implemented
}
// T becomes [number].
addVectors([1], [2]);
// T becomes [number, number] | [number].
addVectors([1, 3], [3]);
I want to prevent this from compiling:
addVectors([1, 3], [3]);
Is it possible to achieve that in TypeScript?
Upvotes: 1
Views: 188
Reputation:
I got it to work by creating a second type parameter which extends the first:
function addVectors<T extends [number, ...number[]], U extends T>(v1: T, v2: U) {
// not implemented
}
// T becomes [number].
addVectors([1], [2]);
// Does not compile.
// "Argument of type '[number]' is not assignable to parameter of type '[number, number]'".
addVectors([1, 3], [3]);
I took it a step further and made addVectors
accept two or more vectors of the same dimension:
function addVectors<T extends [number, ...number[]], U extends T>(...vectors: [T, U, ...U[]]) {
// not implemented
}
addVectors([1], [2]);
addVectors([1, 1], [2, 2], [3, 3]);
// Does not compile.
addVectors([1, 1], [2, 2], [3, 3], [4, 4, 4]);
Upvotes: 0