Почему исчерпывающие проверки работают по-разному для типов объединения? - PullRequest
0 голосов
/ 31 января 2019

Я использую исчерпывающую проверку, как описано в TypeScript Deep Dive

Кажется, проверки исчерпанности работают по-разному для типов объединения по сравнению с типами, которые не являются типами объединения.Почему ??

Например, в приведенном ниже коде обратите внимание, что exhaustivenessCheck1 работает только (не печатает ошибку, когда это не должно), если мы утверждаем, что x.kind равно never.

Тем не менее, exhaustivenessCheck2 работает правильно только в том случае, если мы утверждаем, что x - это never.

type Variant1 = {
    kind: 1 | 2
}

type Variant2 = {
    kind: 1
} | {
    kind: 2
}

const x: Variant1 = { kind: 1 };


function exhaustivenessCheck1(x: Variant1) {
    switch (x.kind) {
        case 1:
        case 2:
            break;
        default:
            const _x: never = x.kind; // OK
            const _y: never = x; // Error
    }
}

function exhaustivenessCheck2(x: Variant2) {
    switch (x.kind) {
        case 1:
            break;
        case 2:
            break;
        default:
            const _x: never = x.kind; // Error
            const _y: never = x; // OK
    }
}

Ссылка на TypeScript Playground (не забудьте включить "строгие проверки на ноль"«)

1 Ответ

0 голосов
/ 31 января 2019

Typescript сужает союзы, когда вы используете type-guard.Путаница возникает из-за того, где объединение.

В Variant1 объединение находится на элементе kind, поэтому машинопись сужает это объединение до never на ветви default.Это означает, что x по-прежнему имеет тип Variant1, а kind по-прежнему доступен на x, просто тип kind на данный момент равен never

In Variant2объединение происходит по самому параметру x, поэтому сужается x.Эта версия также называется дискриминируемым объединением с kind, являющимся дискриминатором.Поскольку все kinds были проверены, default x будет сужен до never и, таким образом, доступ к kind станет ошибкой.

...