我正在创建一个用户定义的类型保护,以确定在运行时获取的(不安全)字符串是否是字符串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
时,我更愿意避免使用string
。
我可以通过将any
的类型签名更改为x
来避免使用number | string | Vendor
,但这仍然不太理想。
有没有办法在enum
上使用字符串执行方括号访问?
答案 0 :(得分:2)
当我没有隐含任何'打开。我怀疑这可能是编译器问题。
如果您只是将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
我注意到在此功能的示例中,它们具有类似的强制转换,或者参数的类型为any
。
另请查看here以获取有关此问题的一些说明。
我仍然认为你需要决定你是否正在寻找名字或价值观。根据您的实施情况,我认为您可能真的在寻找isVendorValue
而不是isVendorName
。 (我不认为询问名称是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
类型。你说&#34;我知道这个类型至少是string
&#34;但这只是不必要地限制了这种方法的用法来测试字符串。
根据您使用该方法的位置,您根本不知道这一点。你知道的是,如果它不是一个字符串,那么它绝对不是Vendor
。
这个想法是,给定一些对象或值(string
与否),确定它是否是此enum
的成员,如果是,则将其视为类型系统中的一个。更广泛适用的方法比不必要的方法更好。
const isVendorValue = (value: any): value is Vendor => {
return typeof value === "string" &&
Object
.keys(Vendor)
.map((key: any) => Vendor[key])
.some((x: any) => x === value);
};