Joh*_*eri 46 enums compare equality typescript
在TypeScript中,我想比较两个包含枚举值的变量.这是我的最小代码示例:
enum E {
A,
B
}
let e1: E = E.A
let e2: E = E.B
if (e1 === e2) {
console.log("equal")
}
Run Code Online (Sandbox Code Playgroud)
使用tsc(v 2.0.3)进行编译时出现以下错误:
TS2365:运算符'==='不能应用于类型'EA'和'E.B'.
同样的,==,!==和!=.我尝试添加const关键字,但似乎没有效果.该打字稿规范说以下内容:
4.19.3 <,>,<=,> =,==,!=,===和!==运算符
这些运算符要求一个或两个操作数类型可以分配给另一个.结果始终是布尔基元类型.
哪(我认为)解释了错误.但是我怎么能绕过它呢?
旁注
我正在使用带有atom-typescript的Atom编辑器,我的编辑器中没有任何错误/警告.但是当我tsc在同一目录中运行时,我得到了上面的错误.我以为他们应该使用相同的tsconfig.json文件,但显然情况并非如此.
Joh*_*eri 15
好吧,我想我发现了一些有用的东西:
if (e1.valueOf() === e2.valueOf()) {
console.log("equal")
}
Run Code Online (Sandbox Code Playgroud)
但我有点惊讶的是文档中没有提到这一点.
art*_*tem 13
还有另一种方法:如果您不希望生成的javascript代码以任何方式受到影响,您可以使用类型转换:
let e1: E = E.A
let e2: E = E.B
if (e1 as E === e2 as E) {
console.log("equal")
}
Run Code Online (Sandbox Code Playgroud)
通常,这是由基于控制流的类型推断引起的.使用当前的typescript实现,只要涉及函数调用,它就会关闭,所以你也可以这样做:
let id = a => a
let e1: E = id(E.A)
let e2: E = id(E.B)
if (e1 === e2) {
console.log('equal');
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,如果id声明函数返回与其文章完全相同的类型,则仍然没有错误:
function id<T>(t: T): T { return t; }
Run Code Online (Sandbox Code Playgroud)
Lui*_*mas 13
就我而言,上述解决方案均无效,原因是我将枚举值强制转换为枚举对象。
之后,我试图知道枚举是否相当于另一个枚举对象......所以我创建了以下通用函数:
public static enumEquals<T>(e: any, e1: T, e2: T): boolean {
const v1 = this.enumValue(e, e1);
return v1 === this.enumValue(e, e2, typeof v1);
}
private static enumValue<T>(enumType: any, value: T, validType?: string) {
let v = enumType[value];
if (!validType) {
return v;
}
if (typeof v !== validType) {
v = enumType[v];
}
if (typeof v !== validType) {
v = enumType[v];
}
return v || null;
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试用例的一个例子:
enum SomeEnum {
VALUE1, VALUE2, VALUE3, VALUE_DEF
}
const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (parsedEnum === SomeEnum.VALUE_DEF) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
该代码不起作用,在我尝试了此问题中给出的解决方案后,我发现enumRefKey有效时打印数字,无效时打印console.log(parsedEnum)文本。VALUE_DEF使用所有其他解决方案都发生了相同的结果:
使用通用方法的解决方案如下所示:
enum SomeEnum {
VALUE1, VALUE2, VALUE3, VALUE_DEF
}
const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (this.enumEquals(SomeEnum, parsedEnum, SomeEnum.VALUE_DEF) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
enums避免与比较相关的所有问题的最佳方法TypeScript是像下面的示例一样声明它们。
而不是这个:
enum SomeEnum {
VALUE1, VALUE2, VALUE3
}
Run Code Online (Sandbox Code Playgroud)
做这个:
enum SomeEnum {
VALUE1 = 'VALUE1', VALUE2 = 'VALUE2', VALUE3 = 'VALUE3'
}
Run Code Online (Sandbox Code Playgroud)
这样,从现在开始,您将不需要将枚举值强制转换或转换为枚举对象,并且如果需要,它始终可以工作。使用此解决方案,以下所有示例均有效,并且它们将返回true:
public static enumEquals<T>(e: any, e1: T, e2: T): boolean {
const v1 = this.enumValue(e, e1);
return v1 === this.enumValue(e, e2, typeof v1);
}
private static enumValue<T>(enumType: any, value: T, validType?: string) {
let v = enumType[value];
if (!validType) {
return v;
}
if (typeof v !== validType) {
v = enumType[v];
}
if (typeof v !== validType) {
v = enumType[v];
}
return v || null;
}
Run Code Online (Sandbox Code Playgroud)
所有这些问题的原因是,当TypeScript编译为枚举时,会像这样JavaScript解析objects
enum SomeEnum {
VALUE1, VALUE2, VALUE3, VALUE_DEF
}
const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (parsedEnum === SomeEnum.VALUE_DEF) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,一旦将枚举解析为JS所有比较问题的原因就变得显而易见,因为我们可能错误地进行了比较,string这number可能最终导致误报结果。以下是解析为 JS 的第二个枚举,效果更好:
enum SomeEnum {
VALUE1, VALUE2, VALUE3, VALUE_DEF
}
const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (this.enumEquals(SomeEnum, parsedEnum, SomeEnum.VALUE_DEF) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
我会像这样定义 Enum 的值并与 ===
const enum AnimalInfo {
Tiger = "Tiger",
Lion = "Lion"
}
let tigerStr = "Tiger";
if (tigerStr === AnimalInfo.Tiger) {
console.log('true');
} else {
console.log('false');
}
Run Code Online (Sandbox Code Playgroud)
如果能够与此比较两个枚举
if (product.ProductType &&
(product.ProductType.toString() == ProductTypes[ProductTypes.Merchandises])) {
// yes this item is of merchandises
}
Run Code Online (Sandbox Code Playgroud)
与ProductTypes是这个 export enum ProductTypes{Merchandises,Goods,...}
唯一对我有用(在打字稿 2.2.1 中)是这样的:
if (E[e1] === E[e2]) {
console.log("equal")
}
Run Code Online (Sandbox Code Playgroud)
这将比较表示名称的字符串(例如“A”和“B”)。
将枚举类型转换为字符串是一项非常有价值的技术。
例如;
if (String(e1) === String(e2)) {
console.log("equal, now actually works!")
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34934 次 |
| 最近记录: |