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")
}
使用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")
}
但我有点惊讶的是文档中没有提到这一点.
art*_*tem 13
还有另一种方法:如果您不希望生成的javascript代码以任何方式受到影响,您可以使用类型转换:
let e1: E = E.A
let e2: E = E.B
if (e1 as E === e2 as E) {
  console.log("equal")
}
通常,这是由基于控制流的类型推断引起的.使用当前的typescript实现,只要涉及函数调用,它就会关闭,所以你也可以这样做:
let id = a => a
let e1: E = id(E.A)
let e2: E = id(E.B)
if (e1 === e2) {
  console.log('equal');
}
奇怪的是,如果id声明函数返回与其文章完全相同的类型,则仍然没有错误:
function id<T>(t: T): T { return t; }
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;
  }
这是我的测试用例的一个例子:
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
}
该代码不起作用,在我尝试了此问题中给出的解决方案后,我发现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
}
enums避免与比较相关的所有问题的最佳方法TypeScript是像下面的示例一样声明它们。
而不是这个:
enum SomeEnum {
  VALUE1, VALUE2, VALUE3
}
做这个:
enum SomeEnum {
  VALUE1 = 'VALUE1', VALUE2 = 'VALUE2', VALUE3 = 'VALUE3'
}
这样,从现在开始,您将不需要将枚举值强制转换或转换为枚举对象,并且如果需要,它始终可以工作。使用此解决方案,以下所有示例均有效,并且它们将返回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;
  }
所有这些问题的原因是,当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
}
正如您所看到的,一旦将枚举解析为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
}
我会像这样定义 Enum 的值并与 ===
const enum AnimalInfo {
Tiger = "Tiger",
Lion = "Lion"
}
let tigerStr = "Tiger";
if (tigerStr === AnimalInfo.Tiger) {
  console.log('true');
} else {
  console.log('false');
}
如果能够与此比较两个枚举
 if (product.ProductType && 
       (product.ProductType.toString() == ProductTypes[ProductTypes.Merchandises])) {
      // yes this item is of merchandises
  } 
与ProductTypes是这个 export enum ProductTypes{Merchandises,Goods,...}
唯一对我有用(在打字稿 2.2.1 中)是这样的:
if (E[e1] === E[e2]) {
  console.log("equal")
}
这将比较表示名称的字符串(例如“A”和“B”)。
将枚举类型转换为字符串是一项非常有价值的技术。
例如;
if (String(e1) === String(e2)) {
    console.log("equal, now actually works!")
}
| 归档时间: | 
 | 
| 查看次数: | 34934 次 | 
| 最近记录: |