javascript - Typescript, generell variadisk fabrikkfunksjon som returnerer tuppel
I TypeScript kan en fabrikkfunksjon opprettes slik, med en definert returtype:
function factory1<T>(object: new () => T): T {
return new object();
}
Hvis jeg vil lage flere forskjellige objekter, kan jeg utvide denne funksjonen til å:
function factory2<T, U>(object1: new () => T, object2: new () => U): [T, U] {
return [new object1(), new object2()];
}
Nå til mitt spørsmål: Kan dette fabrikkmønsteret generaliseres til å ta et vilkårlig antall urelaterte objekttyper og fortsatt returnere en typet tuppel? Eller er det eneste alternativet å gi opp sterk typingen og gå tilbake til å bruke any?
Noe sånt som dette:
function factory3<T extends any[]>(...objects: {new(): any}[]): [...T] {
// BODY
}
Problemet med den siste, factory3, er at vi mister typen T og i stedet får "typeof T". For eksempel:
factory3(ClassA, ClassB, ClassC);
// actually becomes this:
factory3<typeof ClassA, typeof ClassB, typeof ClassC>(...) : [typeof ClassA, typeof ClassB, typeof ClassC] {}
// But we want this to happen instead, which is possible for factory 1:
factory3<typeof ClassA, typeof ClassB, typeof ClassC>(...) : [ClassA, ClassB, ClassC] {}
Svar #1
Selvfølgelig, du kan gjøre fabrikkens rest-argument til en kartlagt array-/tuple-type. Du vil trenge en typepåstand eller noe lignende for å overbevise kompilatoren om at den returnerte verdien i kroppen virkelig er en [...T]:
function factory<T extends any[]>(...ctors: { [K in keyof T]: new () => T[K] }) {
return ctors.map(x => new x) as [...T];
}
Du kan bekrefte at dette fungerer:
class A {
x = 1;
}
class B {
u = "u";
}
class C {
s = true;
}
const objects = factory(A, B, C);
// const objects: [A, B, C]
console.log(JSON.stringify(objects)); // [{"x":1},{"u":"u"},{"s":true}]
Lenke til kode på lekeplassen
