Как я проверяю, что блок переключателя является исчерпывающим в TypeScript?

У меня есть некоторый код:

enum Color {
    Red,
    Green,
    Blue
}

function getColorName(c: Color): string {
    switch(c) {
        case Color.Red:
            return 'red';
        case Color.Green:
            return 'green';
        // Forgot about Blue
    }

    throw new Error('Did not expect to be here');
}

Я забыл обрабатывать Color.Blue случай и я предпочли бы получить ошибку компиляции. Как я могу структурировать свой код, таким образом, что TypeScript отмечает это как ошибку?

58
задан 9 September 2016 в 23:21

3 ответа

Вы не должны использовать never или добавить что-либо в конец Вашего switch.

, Если

  • Ваш switch оператор возвращается в каждом случае
  • , Вы имеете strictNullChecks, флаг компиляции машинописного текста включил
  • , Ваша функция имеет указанный тип
  • возврата, который тип возврата не undefined, или void

Вы получите ошибку, если Ваш switch оператор будет неисчерпывающим, поскольку будет случай, куда ничто не возвращается.

От Вашего примера, если Вы делаете

function getColorName(c: Color): string {
    switch(c) {
        case Color.Red:
            return 'red';
        case Color.Green:
            return 'green';
        // Forgot about Blue
    }
}

, Вы получите следующую ошибку компиляции:

Функция испытывает недостаток в конечном операторе возврата, и тип возврата не включает undefined.

9
ответ дан 1 November 2019 в 14:23

Создавая сверху ответа Ryan, я обнаружил здесь , что нет никакой потребности ни в какой дополнительной функции. Мы можем сделать непосредственно:

function getColorName(c: Color): string {
  switch (c) {
    case Color.Red:
      return "red";
    case Color.Green:
      return "green";
    // Forgot about Blue
    default:
      const _exhaustiveCheck: never = c;
      throw new Error("How did we get here?");
  }
}

Вы видите его в действии здесь в Детской площадке TS

1
ответ дан 1 November 2019 в 14:23

Создайте пользовательскую функцию вместо того, чтобы использовать switch оператор.

export function exhaustSwitch<T extends string, TRet>(
  value: T,
  map: { [x in T]: () => TRet }
): TRet {
  return map[value]();
}

использование В качестве примера

type MyEnum = 'a' | 'b' | 'c';

const v = 'a' as MyEnum;

exhaustSwitch(v, {
  a: () => 1,
  b: () => 1,
  c: () => 1,
});

, Если Вы позже добавляете d к MyEnum, Вы получите ошибку Property 'd' is missing in type ...

-1
ответ дан 1 November 2019 в 14:23

Другие вопросы по тегам:

Похожие вопросы: