typescript - 如何检查 TypeScript 中的开关 block 是否详尽无遗?

标签 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 将其标记为错误?

最佳答案

为此,我们将使用 never 类型(在 TypeScript 2.0 中引入),它表示“不应”出现的值。

第一步是写一个函数:

function assertUnreachable(x: never): never {
    throw new Error("Didn't expect to get here");
}

然后在 default 情况下(或等效地,在 switch 之外)使用它:

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

此时,您会看到一个错误:

return assertUnreachable(c);
       ~~~~~~~~~~~~~~~~~~~~~
       Type "Color.Blue" is not assignable to type "never"

错误消息表明您忘记包含在详尽开关中的情况!如果您遗漏了多个值,您会看到有关例如Color.Blue |颜色.黄色.

请注意,如果您正在使用 strictNullChecks,则需要在 assertUnreachable 调用之前返回 return(否则它是可选的) .

如果你愿意,你可以变得更漂亮一点。例如,如果您使用的是可辨别联合,则出于调试目的恢复断言函数中的可辨别属性可能很有用。它看起来像这样:

// Discriminated union using string literals
interface Dog {
    species: "canine";
    woof: string;
}
interface Cat {
    species: "feline";
    meow: string;
}
interface Fish {
    species: "pisces";
    meow: string;
}
type Pet = Dog | Cat | Fish;

// Externally-visible signature
function throwBadPet(p: never): never;
// Implementation signature
function throwBadPet(p: Pet) {
    throw new Error('Unknown pet kind: ' + p.species);
}

function meetPet(p: Pet) {
    switch(p.species) {
        case "canine":
            console.log("Who's a good boy? " + p.woof);
            break;
        case "feline":
            console.log("Pretty kitty: " + p.meow);
            break;
        default:
            // Argument of type 'Fish' not assignable to 'never'
            throwBadPet(p);
    }
}

这是一个很好的模式,因为您可以获得编译时安全性,以确保您处理了您期望处理的所有情况。如果你确实得到了一个真正超出范围的属性(例如,一些 JS 调用者组成了一个新的 species),你可以抛出一个有用的错误消息。

关于typescript - 如何检查 TypeScript 中的开关 block 是否详尽无遗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39419170/

相关文章:

javascript - 如何添加类型以在 Node v12 中使用 Intl.ListFormat

Typescript 部分接口(interface)重载选择了错误的重载

javascript - 根据变量的值改变div的颜色

javascript - 如何使用 typescript 在第 3 方类上定义方法?

Angular 4 指令错误 : Can't resolve all parameters for directive

javascript - 如何通过nativescript-drop-down插件实现listview中数据的按需排序?

javascript - 单击图标无法导航到新页面

javascript - 如何更快地在索引中加载内联源

node.js - 不能在模块 Electron React Typescript 之外使用 import 语句

html - 传单图例如何通过 typescript 代码在div中设置样式css