2016-04-25 3 views
3

私は、文字列リテラルのシンプルなユニオンタイプを持っており、FFIが "通常の" Javascriptを呼び出すため、その正当性をチェックする必要があります。特定の変数がこれらのリテラル文字列のいずれかのインスタンスであることを保証する方法はありますか実行時にtypeを使用して実行時に文字列リテラルの型の有効性をチェックしていますか?

type MyStrings = "A" | "B" | "C"; 
MyStrings.isAssignable("A"); // true 
MyStrings.isAssignable("D"); // false 

答えて

9

、あなたはそれをwith the keyof operator他の方法で回避を行うことができます。

アイデアは次のとおりです。実行時に文字列型情報が利用できないため、文字列リテラルとしてキーを持つプレーンオブジェクトを定義し、そのオブジェクトのキーの型を作成します。

次のように:

// Values of this dictionary are irrelevant 
const myStrings = { 
    A: "", 
    B: "" 
} 

type MyStrings = keyof typeof myStrings; 

isMyStrings(x: string): x is MyStrings { 
    myStrings.hasOwnProperty(x); 
} 

const a: string = "A"; 
if(isMyStrings(a)){ 
    // ... Use a as if it were typed MyString from assignment within this block: the TypeScript compiler trusts our duck typing! 
} 
1

の線に沿って何かがちょうどType Aliasingであり、それはあなたが本当に行うことはできませんそのため、コンパイルされたJavaScriptコードには存在しません。

MyStrings.isAssignable("A"); 

あなたが何ができますかそれ:あなたのためとして

type MyStrings = "A" | "B" | "C"; 

let myString: MyStrings = getString(); 
switch (myString) { 
    case "A": 
     ... 
     break; 

    case "B": 
     ... 
     break; 

    case "C": 
     ... 
     break; 

    default: 
     throw new Error("can only receive A, B or C") 
} 

isAssignable、することができます質問:

活字体2.1以降0
function isAssignable(str: MyStrings): boolean { 
    return str === "A" || str === "B" || str === "C"; 
} 
+1

これは動作しますが、ブレークは、すぐに 'MyStrings'は、対応する' isAssignable'機能を更新せずに延長されます。手作業の負担が少ないものを望んでいました。 –

+2

それについてはあまりできません。私が書いたように、 'type'部分は厳密にはtypescriptであり、その情報は生成されたjsファイルで失われます。 'type'の代わりに' enum'を使うことができます。 –

+2

もしあなたが努力したいと思えば、タイプと、他のデータソースからのランタイムタイプチェックを行うTSコードを定義するTSコードを生成するためのツールを書くことができます。私はREST APIがC#で書かれたコードを手がかりにし、タイプ定義とタイプを記述する実行時のイントロスペクティブオブジェクトリテラルの両方で、TSにC#データコントラクトをコンパイルしました。理解できるように、そのすべてはTSの範囲外です。 – Alan

関連する問題