Сравните перечисление с перечислением другого типа - PullRequest
1 голос
/ 03 июля 2019

У меня есть перечисления с одинаковыми значениями, но разными именами:

enum EnumA{
  HELLO,
  WORLD
}
enum EnumB{
  HELLO,
  WORLD
}

Как и вы, они сгенерированы внешним источником и имеют одинаковые значения, но используются в компоненте, где это может быть EnumA или EnumB.

let x: EnumA | EnumB = EnumA.HELLO;
// or
let x: EnumA | EnumB = EnumB.HELLO;

Если я хочу проверить привет, мне нужно

if(x === EnumA.HELLO || x === EnumB.HELLO)

Есть ли более простой способ сделать эту проверку или сказать машинописи, что эти два перечисления идентичны?

Что-то вроде:

const x: EnumA | EnumB = EnumB.HELLO;

if(x === EnumA.HELLO) {
    console.log('they are the same')
}

Если я попробую это, я получу предупреждение о машинописи:

Это условие всегда будет возвращать false, так как типы «EnumB.HELLO» и «EnumA.HELLO» не перекрываются.

Но console.log называется! Демо: https://www.typescriptlang.org/play/#code/KYOwrgtgBAouEEEDeBYAUFTUASMAyeA8gDTpZQDqhASngCLoC+6oks8AQqhlrgSWSxVaDNMzToAxgHsQAZwAuUAB4AudpARQAPhogcoAXj0cAdHyIBudOgCWAMwAUyo4eNxN5-EQCUUbuQy8tIANsCmIdIA5o4A5AoAFsAAnlAAhgBOwFCJ2XJpEMCxPkxAA

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Переменные типа объединения сужены в результате анализа потока управления при присваивании . Это означает, что линия

const x: EnumA | EnumB = EnumA.HELLO;

заканчивается сужением типа x до типа EnumA.HELLO, и считается ошибкой сравнивать два несвязанных типа, таких как EnumA.HELLO и EnumB.HELLO.

Если вы хотите предотвратить это, чтобы можно было сравнить x с EnumA и EnumB, вы можете использовать утверждение типа , например:

const x = EnumB.HELLO as EnumA | EnumB;

Тогда сравнение будет работать:

if (x === EnumA.HELLO) { } // okay

Ссылка на код


Но если и EnumA, и EnumB сгенерированы внешним источником, и вы знаете, что они будут идентичны, то это похоже на головную боль, позволяющую им сначала выглядеть как разные типы. Я не знаю достаточно о вашем коде, чтобы предложить, как решить эту проблему ... только импортировать EnumA и игнорировать EnumB? Объединить EnumA и EnumB в один объект и ссылаться только на объединенные EnumAB? Точно сказать не могу.


В любом случае, надеюсь, это поможет. Удачи!

1 голос
/ 03 июля 2019

хорошо, так что это

const x: EnumA | EnumB = EnumB.HELLO;

if(x === EnumA.HELLO) {
    console.log('they are the same')
}

выдает ошибку, поскольку вы сравниваете const с EnumB.HELLO и ts может это увидеть.

если вы получите значение из функции, подобной этой

const a = (): EnumA | EnumB => {
  return EnumA.HELLO;
};
const x: EnumA | EnumB = a();

if (x === EnumB.HELLO) {
  console.log('they are the same');
}

это правильно, и время выполнения пройдет условие, так как это то же самое число

другое решение - сравнить его как число.

const x: number = EnumA.HELLO;

if (x === EnumB.HELLO) {
  console.log('they are the same');
}

и снова среда выполнения пройдет условие, так как это то же самое число ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...