Vytvoriť objekt na základe typy strojom

0

Otázka

Inak sa povedať, že som tento typ

type foo = {
 go: string;
 start: string;
}

Ako môžem dynamicaly vyrobené funkcia, ktorá vráti

{ go: '', start: '' }

Existuje nejaký spôsob, ako na Typ Skript by sme mohli dynamicky generovať prázdny objekt na základe výlučne len typ? Alebo je to nemožné, pretože nemôžeme len slučky

Ja som mal na mysli niečo ako tieto

function generate<T>(T)<T>  {
 const obj = {}
 for (const key of keyof T) {
   obj[key] = ''
 }
 return obj
}
typescript
2021-11-23 19:36:25
2

Najlepšiu odpoveď

2

Keď spustíte Strojom, kompilátor (tsc) na transpile Strojom kód do runnable JavaScript, jazyk je statický typ systému je vymazané. Takže vaše Foo typ (premenovaná na veľké písmená na splnenie TS konvencií) nie je prítomná v akejkoľvek forme v čase behu programu. Nie je nič, čo môžete iterovať cez získať kľúče go a start.


Najjednoduchšou cestou, aby niečo diať pri behu je napísať JavaScript potrebné na to, a potom sa uistite, že Strojom, kompilátor môže dať silné typy, ktoré potrebujete, keď ste písanie. Je to v podstate zvrátiť to, čo sa snažíte urobiť.

Vo vašom prípade: čo robí generate() je potrebné, aby sa práca v režime runtime? Dobre, ak možno predpokladať, že hodnoty generované generate() bude objekty chovu len vtedy, string-oceňované vlastnosti, potom musíme prejsť zoznam kľúče od objektu. Tak čo keby sme sa napísať generate() ak chcete, že, a potom definujte Foo pokiaľ ide o výstup generate() namiesto naopak?

Napríklad:

function generate<K extends PropertyKey>(...keys: K[]) {
  return Object.fromEntries(keys.map(k => [k, ""])) as { [P in K]: string };
}

const myFooObject = generate("go", "start");

type Foo = typeof myFooObject;
/* type Foo = {
    go: string;
    start: string;
} */

console.log(myFooObject)
/* {
  "go": "",
  "start": ""
} */

Tu generate() je všeobecný funkciu, ktorá trvá zoznam kľúče (typ K) a vytvára hodnoty typu s kľúčmi v K a hodnoty typu string. Že {[P in K]: string} je mapované typ ekvivalent Record<K, string> pomocou do Record<K, V> nástroj typu.

Vykonávanie používa Object.fromEntries() vybudovať objekt, a vrátenie typ tvrdil byť správny typ, pretože vidí Strojom Object.fromEntries() ako vracajúci typ, ktorý je príliš široký, pre naše účely.

Každopádne, keď budete volať const myFooObject = generate("go", "start")to vytvára hodnoty typu {go: string; start: string}, ktorý je rovnaký ako váš Foo typ. Takže môžeme jednoducho definovať Foo ako type Foo = typeof myFooObject namiesto robiť ručne. Vám môže ešte urobiť ručne, ale miesto som tu ukazuje sa, že je to oveľa jednoduchšie napísať SUCHÉ kód Strojom, ak začnete s hodnotami a vytvárať typy z nich, namiesto toho sa snaží urobiť to naopak.


Opäť, ak používate Strojom, kompilátor tsc ako je potom zadajte vymazanie vám bráni písanie generate() z definície Foo. Ale...

Ak ste ochotní pridať stavať krok do projektu a vykonať generovanie kódu pomocou Strojom, kompilátor API alebo niečo podobné, to, potom môžete robiť svojvoľné veci s typov. Existujú knižnice, ktoré robiť podobné veci na to, čo chcete; napríklad, ts-auto-mock tvrdí, vytvárať modelové objekty vzhľadom na typ objektu, ktorý vyzerá presne váš prípad použitia.

Ako extra stavať krokom by mohlo byť rozumný prístup pre vás, ale ak pôjdete dole, že trasy, mali by ste si uvedomiť, že nie ste použili len obyčajný Strojom už (a preto téma je pravdepodobne z pôsobnosti na otázku len Strojom značky).

Ihrisko odkaz na kód

2021-11-25 04:07:53
1

Mohli ste to všeobecné, ako je tento:

type foo<T extends string = string> = {
    go: T;
    start: T;
}

const test: foo<''> = {
    go: '',
    start: '',
};

Strojom Ihrisko

2021-11-23 19:47:19

V iných jazykoch

Táto stránka je v iných jazykoch

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................