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

Relaterte artikler