2017-10-19 10 views
0

関数を定義して、私が与えるキーに基づいてオブジェクトの異なる型を返すようにしたい。それは、私が代わりに入力した文字列の列挙型を使用する代わりに、文字列リテラルの、基本的にcreateElement機能がTypeScriptインターフェイスの文字列列挙値を計算されたプロパティキーとして使用

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

にここで使用トリックのようなものです。だから私はこの

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() 
    } 
} 

のようなものを書いたしかし、活字体は、ここで質問が来て、私は計算されたプロパティとしてインターフェイス内enum Kindの価値を置く方法が好きではない、それは

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

を不平を言うようです、私はすでに列挙型で定義された定数を持っている、私は文字列リテラルを使用するのが好きではない、私はこれを動作させることができる方法はありますか?つまり、KindMapの計算されたプロパティキーとしてKind列挙値を使用します。

+2

現在typescriptですバージョンで(https://github.com/Microsoft/TypeScript/issues/16258)[これはサポートされていません]、のように見えます[2.7で修正されるかもしれません](https://github.com/Microsoft/TypeScript/pull/15473) – artem

答えて

0

は時々keyofを持つ単純なオブジェクトは、活字体で列挙型よりも簡単です:

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

私がマッピングされたタイプでgetAnimal()を実装しようとしましたが、バグだらけの推論に実行するように見えました。しかし、クラスを探すのは簡単でした。

getAnimalClass検索も型推論と連携インライン化:

const dog = new kindMap['Dog'](); 
関連する問題