Creați obiect bazat pe tipuri de dactilografie

0

Problema

Ca să nu spun că am acest tip

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

Cum pot dynamicaly făcut-o funcție care va reveni

{ go: '', start: '' }

Există vreo modalitate pe Tip Script am putea genera dinamic gol obiect pe baza exclusiv de tip? Sau acest lucru este imposibil pentru că nu putem buclă

Mă gândeam la ceva de genul

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

Cel mai bun răspuns

2

Când executați Script compiler (tsc) pentru a transpile mașina de Scris cod în runnable JavaScript, un limbaj static tip de sistem este șters. Deci Foo tip (redenumit în majuscule pentru a satisface TS convențiile de denumire) nu este prezent în orice formă în timpul rulării. Nu este nimic nu se poate repeta peste pentru a obține cheile go și start.


Cel mai simplu mod de a obține ceva să se întâmple la runtime este de a scrie JavaScript necesar să o facă, și apoi să asigurați-vă că mașina de Scris compiler poate da puternic tipuri aveți nevoie în timp ce scrii. Aceasta este de fapt inversa a ceea ce încerci să faci.

În cazul tău: ce înseamnă generate() nevoie pentru a lucra la runtime? Ei bine, dacă putem presupune că valorile generate de generate() vor fi obiecte care deține doar string-proprietăți evaluate, atunci trebuie să-l treacă o listă de cheile de la obiect. Deci, ce dacă am scrie generate() pentru a face asta, și apoi să definească Foo în ceea ce privește producția de generate() în loc de invers?

De exemplu:

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": ""
} */

Aici generate() este un generic funcție care ia o listă de chei (de tip K) și produce o valoare de un tip cu cheile în K și valori de tip string. Asta {[P in K]: string} este un mapate tip echivalent cu Record<K, string> folosind cele Record<K, V> tip de utilitate.

Implementarea folosește Object.fromEntries() pentru a construi un obiect, și de tipul de retur este afirmat a fi tipul potrivit pentru mașina de Scris vede Object.fromEntries() ca întorcându-se de un tip care e prea mare pentru scopurile noastre.

Oricum, atunci când apelați const myFooObject = generate("go", "start"), se produce o valoare de tip {go: string; start: string}, care este la fel ca dvs. Foo tip. Deci, putem defini Foo ca type Foo = typeof myFooObject în loc de a face asta manual. Ai putea încă să-l facă manual, dar vreau să-ți arăt aici este că e mult mai ușor să scrie USCAT codul în mașina de Scris dacă începi cu valorile și de a genera tipuri de la ei, în loc de a încerca să-l facă invers.


Din nou, dacă sunteți folosind mașina de Scris compiler tsc ca atare, apoi tastați ștergerea vă împiedică de la scris generate() din definiția de Foo. Dar...

Dacă sunteți dispus să adăugați o construi pas pentru proiectul dumneavoastră și de a efectua generarea de cod folosind mașina de Scris compiler API sau ceva de genul acesta, atunci puteți face lucruri arbitrare cu tipuri. Există biblioteci care fac lucruri similare cu ceea ce vrei; de exemplu, ts-auto-mock pretinde pentru a genera obiecte machete dat un tip de obiect, care se pare ca exact cazul dumneavoastră de utilizare.

Astfel un plus de a construi pas ar putea fi o abordare rezonabilă pentru tine, dar dacă te duci în jos ca traseu vă rugăm să rețineți că nu sunteți folosind pur și simplu mașina de Scris mai (și, prin urmare, subiectul este, probabil, în afara domeniului de aplicare pentru o întrebare cu doar un Script tag).

Loc de joaca link-ul de la cod

2021-11-25 04:07:53
1

Ai putea face generic, astfel:

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

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

Mașina De Scris, Teren De Joacă

2021-11-23 19:47:19

În alte limbi

Această pagină este în alte limbi

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