I am migrating to a newer version of typescript but started getting this error in type guards.
In the else brach, its showing question is of type never rather than showing question is of type Question.
When i run this in typescript v3.9.5 it works fine but in v4.5.4 it gives this error.
Pasting below my code snippet. There is also a ref image of the error in 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'"
}
The error is:
Typescript complains that "Property 'type' does not exist on type 'never'"
CodePudding user response:
The problem is that Question
is a superset of EmptyQuestion
(Question
instances are valid EmptyQuestion
instances). As a result, your type predicate doesn't narrow the question
variable at all; its type in the if
branch is still Question | EmptyQuestion
.
It works if you reverse the type predicate to checking for Question
, since although Question
is a valid EmptyQuestion
, EmptyQuestion
is not a valid 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
}
CodePudding user response:
If you want to go with existing code.
question['type']