web-dev-qa-db-ja.com

TypeScriptで列挙型を比較す​​る方法

TypeScriptでは、enum値を含む2つの変数を比較します。これが私の最小限のコード例です:

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:演算子「===」は、タイプ「E.A」および「E.B」に適用できません。

==!==、および!=と同じです。 constキーワードを追加しようとしましたが、効果がないようです。 TypeScript仕様 は次のことを示しています。

4.19.3 <、>、<=、> =、==、!=、===、および!==演算子

これらの演算子では、一方または両方のオペランドタイプが他方に割り当て可能である必要があります。結果は常にブールプリミティブ型です。

これは(私が思うに)エラーを説明しています。しかし、どうすればそれを回避できますか?

サイドノート
Atomエディターを atom-TypeScript で使用していますが、エディターでエラー/警告が表示されません。しかし、同じディレクトリでtscを実行すると、上記のエラーが発生します。同じtsconfig.jsonファイルを使用することになっていると思いましたが、明らかにそうではありません。

40

別の方法があります:生成された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; }
13
artem

うまくいくものを見つけたと思います:

if (e1.valueOf() === e2.valueOf()) {
  console.log("equal")
}

しかし、ドキュメントのどこにもこれが記載されていないことに少し驚いています。

14

これで2つの列挙型を比較できた場合

 if (product.ProductType && 
       (product.ProductType.toString() == ProductTypes[ProductTypes.Merchandises])) {
      // yes this item is of merchandises
  } 

productTypesがこれであるexport enum ProductTypes{Merchandises,Goods,...}

5
Bellash

このようにEnumの値を定義し、===と比較します

const enum AnimalInfo {
Tiger = "Tiger",
Lion = "Lion"
}

let tigerStr = "Tiger";

if (tigerStr === AnimalInfo.Tiger) {
  console.log('true');
} else {
  console.log('false');
}
3
sendon1982

(TypeScript 2.2.1で)私のために働いた唯一のものはこれでした:

if (E[e1] === E[e2]) {
  console.log("equal")
}

これは、名前を表す文字列(たとえば、「A」と「B」)を比較します。

3
Russ

私の場合、上記の解決策はどれもうまくいきませんでした。理由は、列挙値を列挙オブジェクトにキャストしているからです。

その後、列挙型が別の列挙型オブジェクトと同等であるかどうかを確認しようとしていたので、次のgeneric関数を作成しました。

  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;
    }
    while (typeof v !== validType) {
      v = enumType[v];
    }
    return v;
  }

これは私のテストケースの例です。

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を印刷していませんでした。他のすべてのソリューションを使用しても同じ結果が発生しました。

  • someEnumとしてのparsedEnum
  • parsedEnum.valueOf()
  • SomeEnum [parsedEnum]

ジェネリックメソッドを使用したソリューションは次のようになります

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
}

これが誰かの助けになることを願っています。

0
Luis Limas

TypeScriptの列挙型の例:

enum Example {
   type1,
   type2
};

このオブジェクトにjavascriptに変換されます:

Example {
    '0': 'type1', 'type1': 0,
    '1': 'type2', 'type2': 1
}

TypeScriptの比較列挙に多くの問題がありました。この簡単なスクリプトは問題を解決します:

enum Example {
    type1 = 'type1',
    type2 = 'type2'
};

次に、javascriptでは、オブジェクトは次のように変換されます。

Example {
    'type1': 'type1',
    'type2': 'type2'
}

列挙型を使用する必要がない場合は、使用しない方が良いでしょう。 TypeScriptには、より高度な型があります。詳細はこちら https://www.typescriptlang.org/docs/handbook/advanced-types.html 代わりに使用できます:

type Example = 'type1' | 'type2';
0
W92

コンパイラーはステートメントが常にfalseであり、したがって冗長であることを認識するため、エラーがスローされます。明らかに等しくない2つの変数を宣言してから、それらが等しいかどうかを確認します。

たとえば次のように変更した場合:

enum E {
  A,
  B
}

foo() {
  let e1: E = E.A
  let e2: E
  e2 = foo();

  if (e1 === e2) {
    console.log("equal")
  }
}

bar(): E {
  return E.B
}

エラーなしでコンパイルする必要があります。

副次的に、sth。好む

let e1 = E.A;
if (e1 && e1 === E.B) {
  ...
}

また、この場合のe10(Aは最初の列挙 'オプション'である)であり、したがってfalseは2番目の状態に到達しないことを意味するため、コンパイルもしません。この場合、2番目のステートメントも有効かどうか)

0
seBaka28