2017-09-12 25 views
1

私のプロジェクトでは、タイプガードのようなさまざまなタスクに許容される値の文字列リテラル型と配列が必要です。列挙型オーバーヘッドなしの文字列リテラル型を取得する方法

type Animal = 'cat' | 'dog' | 'rabbit' | 'snake' 
const animals: Animal[] = ['cat', 'dog', 'rabbit', 'snake'] 

それは動作しますが、それは、ソースコード内のキーを数回リストする必要があります。

は、これは、我々が持っているものです。

もう1つの方法は、Get array of string literal type valuesで提案されているように列挙型を使用することですが、実行時に列挙型がコンパイルされたコードが大きくて配列がオーバーヘッドになります。

実行時のオーバーヘッドがない別の方法がありましたが、バグの可能性があるため、将来的に機能するかどうかはわかりません。

const notWidened = <T extends string>(val: T[]) => val 

const animals = notWidened(['cat', 'dog', 'rabbit', 'snake']) 
type Animal = typeof animals[0] 

このスニペットを使用するのが安全なのか、それとも将来的に中断するのかという疑問があります。リテラル文字列型と配列の両方を重複なく取得するには、より良い方法がありますか?

+0

[この質問(https://stackoverflow.com/questions/44480644/typescript-string-union-to-string-array)が関連していてもよいです。 ..更新された[回答](https://stackoverflow.com/a/45486495/2887218)が役立つかどうかを確認してください。 – jcalz

+0

しかしあなたの方法は私にとってもうまく見えます。 – jcalz

+0

少なくとも、私は 'typeof animals [0]'を 'typeof animals [number]'に置き換えることができます。 –

答えて

1

現時点ではこれについての良いドキュメントは見つかりませんでしたが、notWidened()の機能はうまく動作し、バグではありません。型パラメータをstringまたはサブタイプをstringに制限すると、TypeScriptは汎用型変数の文字列リテラルを推論します。したがって、<T extends keyof U>,<T extends string>,<T extends 'a'|'b'>などは、Tの文字列リテラルを推測します。 (同様にTを制約すると、numberまたはbooleanリテラルを推論することもできます)。

あなたのコードは、私が見る限りではまあまあです。 animals0番目の要素は、あなたはそれが'cat'|'dog'|...ある活字体を告げたにも関わらず、実際に'cat'あるので、私は違っするかもしれない唯一のものは、

type Animal = (typeof animals)[number] 

代わりの

type Animal = typeof animals[0] 

です。あなたのものは大丈夫です。

あなたは活字体がanimalsanimals[0]がタイプ'cat'のものであり、animals[1]はタイプ'dog'、などであり、あなたがtuple.tsに機能tuple()のようなものを使用することができタプルであることを考慮したい場合、私は、上記のコメントのよう:

const animals = tuple('cat', 'dog', 'rabbit', 'snake'); 
type Animal = (typeof animals)[number]; // union type 

これはあなたのために便利かもしれません。


TL; DR:コードは問題ありません。

希望があれば、がんばろう!

1

おそらくconst列挙型文字列を使用できますが、実行時オーバーヘッドはありません。これは、コード(Playground)に値をコンパイル:

const enum Animals { 
    Cat = 'cat', 
    Dog = 'dog', 
    Rabbit = 'rabbit', 
    Snake = 'snake' 
} 

alert(Animals.Cat) 

// Generated JavaScript code: 
// alert("cat" /* Cat */); 
関連する問題