簡體   English   中英

嵌套的switch語句可以在TypeScript中窮舉嗎?

[英]Can nested switch statements be exhaustive 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;
            }
    }
}

我可以在內部開關中添加默認值以使其正常工作,但令我驚訝的是我需要一個平面開關就可以了。 這到底是怎么回事?

這里的問題是您尚未處理數據不是您聲明的那樣的情況。 也許某個地方可以強制轉換為任何一個,然后分配letter.type='c' 或就此而言,就這樣稱呼它:

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

雙重強制轉換確保您不會收到編譯器警告,但這不是您在函數中允許的情況。

這是一種排序方式:

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);
        }
    }
}

這樣可以確保在運行時,如果您獲得的數據不是所描述的類型系統,則將對其進行檢查並引發錯誤,但在編譯時,還可以確保您已徹底處理所有情況。

在我編寫上面的代碼時,您收到對exhaustiveCheck(number)的調用的編譯時錯誤,取消注釋其上方的兩行,該錯誤將消失。 由於在默認情況下我們已經覆蓋了AB類型,因此第二次調用了exhaustiveCheck(letter) ,因此剩下的唯一情況是letter的類型為never :這意味着就類型系統而言即使在運行時也有可能發生,但絕不應該發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM