2017-10-19 4 views
0

Je souhaite définir une fonction renvoie un type d'objet différent en fonction de la clé que je donne. Il est fondamentalement comme le truc utilisé ici en fonction createElementUtilisation de la valeur de chaîne enum dans l'interface TypeScript en tant que clé de propriété calculée

https://github.com/Microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L3117

Cependant, au lieu de chaîne littérale, je veux utiliser le type de chaîne à la place ENUM. J'ai donc écrit quelque chose comme ça

class Dog {} 
class Cat {} 
class Bird {} 

enum Kind { 
    Dog = 'Dog', 
    Cat = 'Cat', 
    Bird = 'Bird' 
} 

interface KindMap { 
    [Kind.Dog]: Dog 
    [Kind.Cat]: Cat 
    [Kind.Bird]: Bird 
} 

function getAnimal<K extends keyof KindMap> (key: K): KindMap[K] { 
    switch (key) { 
    case Kind.Dog: 
     return new Dog() 
    case Kind.Cat: 
     return new Cat() 
    case Kind.Bird: 
     return new Bird() 
    } 
} 

Cependant, tapuscrit semble n'aime pas la façon dont je mets la valeur de la enum Kind dans l'interface comme la propriété calculée, il se plaint

A computed property name in an interface must directly refer to a built-in symbol. 

Voici la question , J'ai déjà les constantes définies dans l'enum, je n'aime pas utiliser la chaîne littérale, y at-il un moyen que je peux faire fonctionner cela? Ce qui signifie utiliser la valeur de Kind enum comme clé de propriété calculée dans le KindMap.

+2

[Non pris en charge] (https://github.com/Microsoft/TypeScript/issues/16258) dans la version actuelle de tapuscrit, ressemble [Il pourrait être corrigé dans 2.7] (https://github.com/Microsoft/TypeScript/pull/15473) – artem

Répondre

0

Parfois, un simple objet avec keyof est plus simple qu'un ENUM dactylographiée:

class Dog { } 
class Cat { } 

const kindMap = { 
    Dog, 
    Cat 
}; 

type KindMap = typeof kindMap; 

function getAnimalClass<K extends keyof KindMap>(key: K): KindMap[K] { 
    return kindMap[key]; 
} 

// These types are inferred correctly 
const DogClass = getAnimalClass('Dog'); 
const dog = new DogClass(); 

const CatClass = getAnimalClass('Cat'); 
const cat = new CatClass(); 

Try it in TypeScript Playground

J'ai essayé de mettre en œuvre getAnimal() avec des types cartographiés mais semble fonctionner en inférence buggy. Mais regarder la classe était plus facile.

Inlining la getAnimalClass recherche fonctionne également avec l'inférence de type:

const dog = new kindMap['Dog']();