打字稿中的类型保护正在缩小到从不打字

Type guards in typescript are narrowing to never type

我正在迁移到较新版本的打字稿,但开始在类型保护中收到此错误。
在 else 分支中,它的显示问题是类型 never 而不是显示问题是类型问题。 当我 运行 在打字稿 v3.9.5 中运行时它工作正常但在 v4.5.4 中它给出了这个错误。 粘贴在我的代码片段下方。在 vs code

中也有错误的参考图像
export enum QuestionTypesEnum {
    TYPE1 = 'type1',
    TYPE2 = 'type2'
}

export type McqSingle = {
    hash: string
    type: QuestionTypesEnum
    answer: string;
}

export type McqMultiple = {
    hash: string
    type: QuestionTypesEnum
    answers: string[]
}

export type Question =
| McqSingle
| McqMultiple

type EmptyQuestion = { hash: string }

const isEmptyQuestion  = (question: Question | EmptyQuestion): question is EmptyQuestion => {
    return !('type' in question)
}

let question: Question | EmptyQuestion = { hash: 'saas', type: QuestionTypesEnum.TYPE1 }

if (isEmptyQuestion(question)) {

}
else {
    question.type  // <-- Typescript complains that "Property 'type' does not exist on type 'never'"
}

Playground link

错误是:

Typescript complains that "Property 'type' does not exist on type 'never'"

TS error in vs code

问题是 QuestionEmptyQuestion 的超集(Question 实例是有效的 EmptyQuestion 实例)。结果,您的类型谓词根本不会缩小 question 变量;它在 if 分支中的类型仍然是 Question | EmptyQuestion.

如果将类型谓词反转为检查 Question,它会起作用,因为尽管 Question 是有效的 EmptyQuestion,但 EmptyQuestion 不是有效的 Question:

const isQuestion  = (question: Question | EmptyQuestion): question is Question => {
    return 'type' in question;
};

// ...

if (isQuestion(question)) {
    question.type
    // ^? −−−− type is Question
} else {
    question.hash
    // ^? −−−− type is EmptyQuestion
}

Playground link