Typescript Can';t为字符串枚举创建用户定义的类型保护
我正在创建一个用户定义的类型保护,以确定在运行时获取的(不安全的)字符串是否是字符串Typescript Can';t为字符串枚举创建用户定义的类型保护,typescript,Typescript,我正在创建一个用户定义的类型保护,以确定在运行时获取的(不安全的)字符串是否是字符串enum的成员: enum Vendor { ACME = "Acme Co.", FOOBAR = "Foo Bar Industries" } export let isVendor = (x: string | Vendor): x is Vendor => { return !!Vendor[x]; }; 当我尝试编译上述代码时,我收到以下消息: [ts] Element impli
enum
的成员:
enum Vendor {
ACME = "Acme Co.",
FOOBAR = "Foo Bar Industries"
}
export let isVendor = (x: string | Vendor): x is Vendor => {
return !!Vendor[x];
};
当我尝试编译上述代码时,我收到以下消息:
[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];
};
…但是当我知道类型至少是一个字符串时,我宁愿避免使用any
通过将x
的类型签名更改为number | string | Vendor
,我可以避免使用any
,但这仍然不够理想
是否有任何方法可以使用字符串对enum
执行方括号访问?当打开“无隐式任何”时,我确实会遇到该错误。我怀疑这可能是编译器的问题
如果您只是将x
强制转换为any
:
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
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
类型。您会说“我知道类型至少是一个字符串
”,但这不必要地限制了该方法在测试字符串时的使用
你并不知道,这取决于你在哪里使用这种方法。您知道的是,如果它不是字符串,那么它肯定不是供应商
其思想是,给定某个对象或值(字符串
或非),确定它是否是此枚举
的成员,然后将其视为类型系统中的成员。更广泛适用的方法比不必要的狭窄方法更好
const isVendorValue = (value: any): value is Vendor => {
return typeof value === "string" &&
Object
.keys(Vendor)
.map((key: any) => Vendor[key])
.some((x: any) => x === value);
};
我的意图是拥有一个用户定义的类型保护,而不是一个返回布尔值的函数。您的示例不向编译器传递类型信息,它们只返回true或false。这是只有用户定义的类型保护才能完成的。@Rick您希望返回什么!!供应商[x]
除了返回布尔值
?抱歉,我正在阅读这个概念…用户定义的类型guard返回boolean,但它不仅仅返回bool。见:
const isVendorValue = (value: any): value is Vendor => {
return typeof value === "string" &&
Object
.keys(Vendor)
.map((key: any) => Vendor[key])
.some((x: any) => x === value);
};