2017-08-30 15 views
1

私は、実行時にフェッチ(危険な)文字列は、文字列enumのメンバーであるかどうかを判断するために、ユーザー定義型のガードを作成していため、ユーザー定義型のガードを作成できません私は、次の受信、上記のコードをコンパイルしようとすると、次のようには、文字列の列挙型

[ts] Element implicitly has an 'any' type because expression is not of type 'number'. 
(parameter) x: string 

一つの可能​​な修正は次のとおりです。

export let isVendor = (x: any): x is Vendor => { 
    return !!Vendor[x]; 
}; 

...私はタイプが少なくともstringであることを知ったときにanyを避けることを好む。

Iはnumber | string | Vendorxの型シグネチャを変更することにより、anyの使用を避けることができ、これはまだ理想に満ちません。

文字列を使用してenumに角括弧でアクセスする方法はありますか?

答えて

2

「暗黙の任意」がオンになっていると、エラーが表示されます。私はこれがコンパイラの問題かもしれないと思う。

それはあなただけanyxをキャストした場合に動作します:

enum Vendor { 
    A = "a", 
    B = "b" 
} 

const isVendor = (x: string | Vendor): x is Vendor => { 
    return !!Vendor[<any>x]; 
}; 

console.info(isVendor("A")); // true 
console.info(isVendor("a")); // false 
console.info(isVendor("C")); // false 

私は、この機能の例では、彼らは同様のキャストを持っているか、他のパラメータはタイプanyであることに気づきます。

この問題の説明については、hereもチェックしてください。

名前や値を探しているかどうかを判断する必要があると私は考えています。あなたの実装に基づいて、私はisVendorNameではなく、isVendorValueを実際に探しているかもしれないと思います。 (私はそれも名前がVendorであれば、それはないですので、依頼する意味があるとは思わない、あなたは値がVendorであるかどうかを知りたい。):

enum Vendor { 
    A = "a", 
    B = "b" 
} 

// doesn't make sense. the name cannot be a Vendor. 
const isVendorName = (name: string | Vendor): name is Vendor => { 
    return !!Vendor[<any>name]; 
}; 

// requires ES7, see below 
const isVendorValue = (value: string | Vendor): value is Vendor => { 
    return Object.values(Vendor).some((x: any) => x === value); 
}; 

console.info(isVendorName("A"));  // true 
console.info(isVendorName("a"));  // false 
console.info(isVendorName("C"));  // false 
console.info(isVendorName(Vendor.A)); // false 

console.info(isVendorValue("A"));  // false 
console.info(isVendorValue("a"));  // true 
console.info(isVendorValue("C"));  // false 
console.info(isVendorValue(Vendor.A)); // true 

Object.valuesが明らかにそうES7ですここに別の実装があります。値は実行時に変更されないため、値をキャッシュすることで恩恵を受ける可能性があります。私は今、私はそれについて考えることを示唆している

const isVendorValue = (value: string | Vendor): value is Vendor => { 
    return Object 
     .keys(Vendor) 
     .map((key: any) => Vendor[key]) 
     .some((x: any) => x === value); 
}; 

もう一つは、あなたの提案に反して、パラメータは、おそらく実際にとにかく種類anyのものでなければならないということです。 「少なくともタイプがstringであることはわかっていますが、このメソッドの使用をテスト文字列に限定するだけで十分です。

あなたは本当にそれを知っていない、方法を使用する場所に応じて。あなたが知っているのは、それが文字列でなければ、間違いなくVendorではないということです。

アイデアは、あるオブジェクトまたは値(stringかどうか)が与えられた場合、それがenumのメンバであるかどうかを判断し、それがタイプシステムで1として扱われるかどうかを判断します。不必要に狭い方法よりも幅広く適用できる方法が優れています。

const isVendorValue = (value: any): value is Vendor => { 
    return typeof value === "string" && 
     Object 
     .keys(Vendor) 
     .map((key: any) => Vendor[key]) 
     .some((x: any) => x === value); 
}; 
+0

私の意図は、ユーザー定義の型ガードであり、 'boolean'を返す関数ではありませんでした。あなたの例はコンパイラに型情報を伝えるのではなく、単に真または偽を返します。これは、ユーザー定義型ガードだけが達成できるものです。 – Rick

+0

@Rickあなたは 'return !!ベンダー[x]'が 'boolean'以外にもどると期待していますか? K申し訳ありませんが、このコンセプトを読んでいます... –

+0

ユーザー定義の型ガードはブール値を返しますが、単純にboolを返す以外のことはしません。参照:https://basarat.gitbooks.io/typescript/docs/types/typeGuard.html – Rick

関連する問題