javascript - Typescript längd på en generisk typ
Jag har en funktion som ser ut som
export function is<T extends any[]>(...klasses): Predictor<T> {
return (...variables: T) => {
return variables
.every((variable, index) => variable instanceof klasses[index]);
}
}
I det här exemplet vill jag försäkra mig om att klasses har samma längd som arrayen som T är. Hur gör jag klasses av typen any[] med samma längd som T?
Uppdatering
Baserat på kommentarerna har jag uppdaterat detta till
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]);
}
}
Svar #1
Här är en annan lösning som använder ett andra typargument för längden. Jag såg att du inte vill ha ett annat typargument, men jag lägger till det för fullständighetens skull ändå.
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
Svar #2
Du kan fråga längden på klasserna-arrayen, och sedan begränsa variablernas längd till att vara samma:
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
Men i det här fallet kommer du inte kunna specificera variablers typ i förväg. Om du kan ändra implementeringen för att tillåta automatisk härledning av klassers typ, kan du gå vidare med:
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
