【问题标题】:TypeScript ensure all cases are handled for union type [duplicate]TypeScript 确保为联合类型处理所有案例 [重复]
【发布时间】:2020-04-28 07:34:45
【问题描述】:

我有一个看起来像这样的联合类型:

type Action = 'foo' | 'bar' | 'baz';

我希望编译器在有人扩展它时抛出错误(通过添加另一种类型)。

看看这段代码:

type Action = 'foo' | 'bar' | 'baz';

function create(action: Action) {
    let something;
    switch (action) {
        case 'foo':
            something = action.toLowerCase();
            break;
        case 'bar':
            something = action.toUpperCase();
            break;
    }

    return something;
}

如您所见,baz 案例没有以任何方式处理,看起来对于打字稿来说完全没问题。你知道如何强制 TS 在这里抛出错误(因为 baz 类型没有被处理)?

游乐场:here

【问题讨论】:

  • 您如何定义该规则? TS在什么情况下应该抛出这个错误?这个定义还会打破多少其他守则?国际海事组织。我不认为这是对一种语言的合理期望。
  • 我不知道。也许像switch(action): Action 这样的东西。我看到 const obj: Record<Action, string> 工作正常 - 您必须声明所有 3 个属性。所以也许我会选择这种方式。基本上我想从 TS 获得信息,当开发人员扩展联合类型时,某些情况需要在代码中的某处处理
  • 但是从TS的角度来看,是不需要处理的。并且用所有必需的属性实例化 Type 与 “我希望这个特定的函数来处理这个特定的联合类型的所有可能值” 不同。或者您是否希望每个使用联合类型(在互联网上的每个 TS 代码中) 的函数都需要处理该联合类型的所有可能值?您将如何定义语言级别的规则?您将如何定义该规则应适用于哪些函数和哪些联合类型?

标签: typescript union-types


【解决方案1】:

如果您为函数指定 返回类型,TS 会告诉您您没有处理特定情况,因为有可能返回 undefined 值由于未处理的案件。

例如,在您的 Playground 中尝试以下操作:

type Action = 'foo' | 'bar' | 'baz';

function create(action: Action): string {
    let something;
    switch (action) {
        case 'foo':
            something = action.toLowerCase();
            break;
        case 'bar':
            something = action.toUpperCase();
            break;
    }

    return something;
}

您会在 return 语句中注意到以下错误:

键入'字符串 | undefined' 不能分配给类型 'string'。 类型“未定义”不可分配给类型“字符串”。(2322)

现在,添加一个案例来处理baz,编译错误就会消失。

【讨论】:

  • 谢谢,这很有帮助,我会采用这种方法!
猜你喜欢
  • 2018-10-17
  • 2020-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多