typescript - 在 TypeScript 的 if-else 语句中用尽枚举

标签 typescript

TypeScript(在严格模式下)将以下函数的返回类型推断为 1 |未定义:

enum E {A, B};
const f = (x: E) => {
  if (x === E.A) {
    return 1;
  } else if (x === E.B) {
    return 1;
  }
}

如何确保将类型推断为数字(因为枚举已用尽)?目前我添加 ... else { throw undefined; },但这意味着如果我忘记实际用尽枚举中的所有选项,TypeScript 将无法捕获它。它适用于 switch 语句:

const g = (x: E) => {
  switch (x) {
    case E.A:
      return 1;
    case E.B:
      return 1;
  }
};

所以它不能与 if-else 一起使用似乎很奇怪,我觉得我遗漏了一些明显的东西。

最佳答案

根据评论中的讨论(感谢大家的投入),这是一个缺失的功能 (Github issue here)。目前唯一的解决方法是使用 ... else { ((x: never) => { throw undefined; })(x); },这很丑陋,但会确保类型被正确推断,并且如果枚举没有完全耗尽则会产生错误。

更新:实际上,我认为最好的方法是使用效用函数

export const assertNever = (arg: never): never => {
  throw 'assertNever';
};

并像这样使用它:

if (value === ...) {
  ...
} else {
  return assertNever(value);
}

或者(如果返回类型无关紧要)像这样:

if (value === ...) {
  ...
} else {
  assertNever(value);
}

或者,在三元的情况下,像这样:

value === ...
  ? ...
  : value === ...
  ? ...
  : assertNever(value)

关于typescript - 在 TypeScript 的 if-else 语句中用尽枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48975236/

相关文章:

javascript - Ionic v2 + CORS 预检访问控制允许方法

javascript - Backbone 和 TypeScript,一段不幸的婚姻 : Building a type-safe "get"?

javascript - 如何模拟作为参数传递的回调的调用?

javascript - 自定义重试功能

knockout.js - typescript 中的无名函数?

angular - 为什么添加选择器标签会导致网络应用程序卡住?

typescript - 如何修复 VSCode 中的 "Property XX does not exist on type ' CombinedVueInstance”错误?(Vue 和 Typescript)

typescript - 字符串类型和字符串类型有什么区别?

typescript - 使用 CDK 将文件上传到 S3 存储桶

组件中的 Angular2 : Uncaught (in promise): Quotes are not supported for evaluation!