I have a function that looks like
export function is<T extends any[]>(...klasses): Predictor<T> {
return (...variables: T) => {
return variables
.every((variable, index) => variable instanceof klasses[index]);
}
}
In this example, I want to make sure klasses
is of the same length as the array that T
is. How do make klasses
of type any[]
with the same length as T
?
Update
Based on the comments, I've updated this to
export function is<T extends Array<any>>(...klasses: any[] & {length: T['length']}): Predictor<T> {
return (...variables: T) => {
return variables
.every((variable, index) => variable instanceof klasses[index]);
}
}
Here's another solution using a second type argument for the length. I saw that you don't want another type argument, but I'll add it for completeness sake anyway.
export function is<L extends number, T extends any[] & {length: L}>(...klasses: any[] & {length: L}) {
return (...variables: T) => {
return variables
.every((variable, index) => variable instanceof klasses[index]);
}
}
is(Number, String)(1, 1); // ok
is(Number, String)(1); // error
You can query the length of the classes array, then restrict variables length to be the same:
export function is<TClasses extends any[]>(...klasses: TClasses) {
return (...variables: any[] & { length: TClasses['length'] }) => {
return variables
.every((variable, index) => variable instanceof klasses[index]);
}
}
is(Number, String)(1, 1); // ok
is(Number, String)(1); // error: Types of property 'length' are incompatible
But in this case you won't be able to specify variables type upfront. If you can change implementation to allow automatic inference of classes type, you can go with:
export function is<T extends any[]>() {
return <TClasses extends any[]>(...klasses: TClasses) =>
(...variables: T & { length: TClasses['length'] }) =>
variables.every((variable, index) => variable instanceof klasses[index]);
}
is<string[]>()(Number, String)('1', '1'); // ok
is<string[]>()(Number, String)(1, 1); // error: not assignable to type 'string[]'
is()(Number, String)(1); // error: Types of property 'length' are incompatible
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With