简体   繁体   English

嵌套的switch语句可以在TypeScript中穷举吗?

[英]Can nested switch statements be exhaustive in TypeScript?

It looks like the following code doesn't type check in TypeScript. 看起来以下代码没有在TypeScript中键入check。

interface A {
    type: 'a',
    number: Number
}

interface B {
    type: 'b',
    number: Number
}

type Letter = A | B

interface One {
    type: 'one'
}

interface Two {
    type: 'two'
}

type Number = One | Two;


function we(letter: Letter): boolean { // claims boolean isn't always returned
    switch (letter.type) {
        case 'a':
            return true;

        case 'b':
            const number = letter.number;
            switch (number.type) {
                case 'one':
                    return true;
                case 'two':
                    return true;
            }
    }
}

I can add a default to the inner switch to get it working but I'm surprised that I need to given that a flat switch works just fine. 我可以在内部开关中添加默认值以使其正常工作,但令我惊讶的是我需要一个平面开关就可以了。 What exactly is going on here? 这到底是怎么回事?

The problem here is that you haven't handled the case where the data isn't what you declared that it would be. 这里的问题是您尚未处理数据不是您声明的那样的情况。 Maybe somewhere there could be casts to any and then assigning letter.type='c' . 也许某个地方可以强制转换为任何一个,然后分配letter.type='c' Or for that matter just call it like this: 或就此而言,就这样称呼它:

we({type: 'c'} as any as Letter);

The double cast ensures you get no compiler warnings, but that isn't a case you've allowed for in the function. 双重强制转换确保您不会收到编译器警告,但这不是您在函数中允许的情况。

Here's one way to sort it: 这是一种排序方式:

function exhaustiveCheck(value: never): never {
  throw(new Error('switch was not exhaustive'));
}

function we(letter: Letter): boolean {
    switch (letter.type) {
        case 'a':
            return true;

        case 'b':
            const number = letter.number;
            switch (number.type) {
                case 'one':
                    return true;
                // case 'two':
                //     return true;
                default:
                  return exhaustiveCheck(number);
            }
        default: {
          return exhaustiveCheck(letter);
        }
    }
}

This ensures that at runtime, if you get data that wasn't as the type system described it will be checked and throw an error, but at compile time it also ensures you have exhaustively handled all of the cases. 这样可以确保在运行时,如果您获得的数据不是所描述的类型系统,则将对其进行检查并引发错误,但在编译时,还可以确保您已彻底处理所有情况。

As I wrote the code above, you get a compile time error for the call to exhaustiveCheck(number) , uncomment the two lines above it and the error will go away. 在我编写上面的代码时,您收到对exhaustiveCheck(number)的调用的编译时错误,取消注释其上方的两行,该错误将消失。 The second call to exhaustiveCheck(letter) is accepted because in the default case we have already covered both of the types A and B so the only case remaining is that letter has the type never : that means so far as the type system is concerned it should never happen even though at runtime it possible could happen. 由于在默认情况下我们已经覆盖了AB类型,因此第二次调用了exhaustiveCheck(letter) ,因此剩下的唯一情况是letter的类型为never :这意味着就类型系统而言即使在运行时也有可能发生,但绝不应该发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么此 TypeScript 详尽的开关检查不起作用? - Why is this TypeScript exhaustive switch check not working? 如何通过详尽的 switch-case 语句获得一致的返回? - How can I have consistent-return with exhaustive switch-case statements? 除了 switch 和三元运算符之外,typescript 或 javascript 中嵌套 If else 语句的替代方法 - Alternative for nested If else statements in typescript or javascript otherthan switch and ternary operator TypeScript 可区分联合 - 在详尽的 If 语句之后分配之前使用的变量 - TypeScript Discriminated Union - Variable Used Before Assigned after Exhaustive If Statements 如何在 typescript 开关语句中进行接口检查? - How can i have a interface check in typescript switch statements? 如何检查 TypeScript 中的开关块是否详尽无遗? - How do I check that a switch block is exhaustive in TypeScript? TypeScript 中的条件属性和 switch 语句 - Conditional properties and switch statements in TypeScript 为什么 Typescript 不能通过深度/嵌套属性推断 Switch 语句中的类型 - Why doesn't Typescript Infer Type in Switch Statements over Deep/Nested Properties switch case语句中的Typescript类型安全性 - Typescript type safety in switch case statements Typescript,如何摆脱这些switch语句 - Typescript, how to get rid of these switch statements
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM