Creare un oggetto in base a tipi dattiloscritto

0

Domanda

Per timore di dire che ho questo tipo

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

Come posso dynamicaly fatto una funzione che ritorna

{ go: '', start: '' }

C'è un modo sul Tipo di Script si potrebbe generare dinamicamente oggetto vuoto basato esclusivamente solo tipo? O questo è impossibile, perché non possiamo solo loop

Stavo pensando a qualcosa di simile a questi

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

Migliore risposta

2

Quando si esegue la Registrazione del compilatore (tsc) per transpile Dattiloscritto codice eseguibile JavaScript, il linguaggio è di tipo statico, sistema viene cancellato. Così il vostro Foo tipo (rinominato in maiuscolo per soddisfare TS convenzioni di denominazione) non è presente in nessuna forma in fase di runtime. Non c'è nulla che si può scorrere con la consegna delle chiavi go e start.


Il modo più semplice per ottenere qualcosa accada in fase di runtime è quello di scrivere il codice JavaScript necessario per farlo, e quindi assicurarsi che il Dattiloscritto compilatore è in grado di dare forti tipi di cui avete bisogno durante la scrittura. Questo è praticamente l' inverso di quello che stai cercando di fare.

Nel tuo caso: che cosa significa generate() necessario per il lavoro in fase di esecuzione? Beh, se si può supporre che i valori generati dall' generate() saranno gli oggetti che tiene solo stringvalori di proprietà, quindi abbiamo bisogno di passare un elenco dei tasti di oggetto. Così che cosa se scriviamo generate() per fare questo, e quindi definire Foo in termini di output di generate() invece di fare il contrario?

Per esempio:

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

Qui generate() è una generica funzione che prende una lista di chiavi (di tipo K) e produce un valore di un tipo con le chiavi in K e valori di tipo string. Che {[P in K]: string} è una mappata di tipo equivalente a Record<K, string> utilizzando il Record<K, V> tipo di utilità.

L'implementazione utilizza Object.fromEntries() per creare l'oggetto, e il tipo di ritorno è affermato di essere il tipo giusto perché Dattiloscritto vede Object.fromEntries() come la restituzione di un tipo che è troppo ampia per i nostri scopi.

Comunque quando si chiama const myFooObject = generate("go", "start"), che genera un valore di tipo {go: string; start: string}che è lo stesso del tuo Foo tipo. Così si può definire Foo come type Foo = typeof myFooObject invece di farlo manualmente. Si potrebbe ancora farlo manualmente, ma il punto che vi sto mostrando è che è molto più facile scrivere un SECCO codice in Macchina, se si inizia con i valori e generare tipi da loro, invece di cercare di farlo in un altro modo.


Di nuovo, se si utilizza il Dattiloscritto del compilatore tsc come-è, quindi digitare la cancellazione impedisce di scrivere generate() dalla definizione di Foo. Ma...

Se siete disposti ad aggiungere un passaggio di generazione per il vostro progetto e di eseguire la generazione di codice utilizzando il Dattiloscritto del compilatore API o qualcosa di simile, si può fare arbitrario cose con i tipi. Ci sono librerie che fanno cose simili a ciò che si desidera, ad esempio, ts-auto-mock crediti per generare gli oggetti mock dato un tipo di oggetto, che sembra esattamente il tuo caso d'uso.

Ad un extra di costruire passo potrebbe essere un approccio ragionevole per voi, ma se si va giù che il percorso dovrebbe notare che non stai usando semplicemente Dattiloscritto più (e quindi l'argomento è probabilmente fuori portata per una domanda con solo un Dattiloscritto tag).

Giochi link al codice

2021-11-25 04:07:53
1

Si potrebbe fare generica, come questo:

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

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

Dattiloscritto Giochi

2021-11-23 19:47:19

In altre lingue

Questa pagina è in altre lingue

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