Créer un objet basé sur les types de caractères d'imprimerie

0

La question

De peur de dire que j'ai ce type

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

Comment puis-je dynamicaly fait une fonction qui retournera

{ go: '', start: '' }

Est-il possible sur le Type de Script, on pourrait générer dynamiquement le vide d'objet basé sur le seul il suffit de taper? Ou c'est impossible parce que nous ne pouvons pas juste de la boucle

Je pensais à quelque chose comme ces

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

La meilleure réponse

2

Lorsque vous exécutez le fichier d'enregistrement du compilateur (tsc) pour transpile Tapuscrit code exécutable JavaScript, le langage du système de type statique est effacé. Si votre Foo type (renommé en majuscules pour répondre à TS les conventions de nommage) n'est pas présent dans le formulaire au moment de l'exécution. Il n'y a rien que vous pouvez parcourir à la remise des clés go et start.


La façon la plus simple d'obtenir quelque chose pour arriver à l'exécution est d'écrire le code JavaScript nécessaire pour le faire, puis assurez-vous que le Tapuscrit compilateur peut vous donner les fortes vous avez besoin pendant que vous l'écrivez. C'est essentiellement l' inverse de ce que vous essayez de faire.

Dans votre cas: ce n' generate() besoin pour travailler au moment de l'exécution? Eh bien, si nous pouvons supposer que les valeurs générées par generate() seront des objets ayant seulement stringvaleur des propriétés, alors nous avons besoin de passer à une liste des clés de l'objet. Alors que faire si nous écrire generate() pour le faire, et puis de définir Foo en termes de la sortie de generate() au lieu de l'inverse?

Par exemple:

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

Ici generate() est un générique de fonction qui prend une liste de clés (de type K) et produit une valeur d'un type avec des touches de K et les valeurs de type string. Que {[P in K]: string} est mappé type équivalent à Record<K, string> à l'aide de la Record<K, V> de type utilitaire.

La mise en œuvre utilise Object.fromEntries() pour construire l'objet, et le type de retour est affirmé être le type de droit parce que Tapuscrit voit Object.fromEntries() comme retournant un type qui est trop large pour nos fins.

De toute façon, lorsque vous appelez const myFooObject = generate("go", "start")il produit une valeur de type {go: string; start: string}, qui est le même que celui de votre Foo type. Nous pouvons donc définir Foo comme type Foo = typeof myFooObject au lieu de le faire manuellement. Vous pourrait toujours le faire manuellement, mais le point que je vais les montrer ici, c'est que c'est beaucoup plus facile d'écrire à SEC code en caractères d'imprimerie si vous commencez avec des valeurs et de générer des types d'eux, au lieu d'essayer de le faire dans l'autre sens.


Encore une fois, si vous utilisez le Tapuscrit compilateur tsc que-est, puis le type d'effacement ne vous empêche de l'écriture generate() à partir de la définition de Foo. Mais...

Si vous êtes prêt à ajouter une étape de génération de votre projet et d'effectuer la génération de code à l'aide de la Tapuscrit compilateur API ou quelque chose comme cela, vous pourrez alors faire arbitraire des choses avec les types. Il y a des bibliothèques qui font des choses similaires à ce que vous voulez, par exemple, ts-auto-se moquer de revendications pour générer des objets fantaisie donné un type d'objet, qui ressemble exactement à votre cas d'utilisation.

Un tel supplément de construire étape pourrait être une approche raisonnable pour vous, mais si vous allez dans cette voie, vous devez noter que vous n'êtes pas en utilisant simplement le Tapuscrit plus (et donc le sujet est probablement hors de portée pour une question avec juste un Tapuscrit de la balise).

Aire de jeux lien vers le code

2021-11-25 04:07:53
1

On pourrait le rendre générique, comme ceci:

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

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

Tapuscrit De L'Aire De Jeux

2021-11-23 19:47:19

Dans d'autres langues

Cette page est dans d'autres langues

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