Let's say I have a list of conditionals and I want to handle every possible value of type. If I added a new type in the future and I forget to handle it, I want an error - at least a run-time error, but ideally a compiler error so I catch my mistake before I deploy.
How can I assert that a variable is of type never?
type Job = { type: 'add'; payload: any } | { type: 'send'; payload: any }
const handleJob = (job: Job) => {
const add = (job: Job) => {
console.log(job)
}
const send = (job: Job) => {
console.log(job)
}
if (job.type === 'add') {
add(job)
} else if (job.type === 'send') {
send(job)
} else {
// `job` is actually type `never` here,
// this error won't ever be thrown unless additional strings are added to the `Job.type` schema.
throw new Error(`Unhandled job.type "${(job as Job).type}".`)
}
}
You can introduce a
never-returning function which only accepts an argument of thenevertype, meaning that the compiler will only be happy if it doesn't actually expect the function to get called. This function is usually calledassertNever(). Here's one way to write it:If it does get called then you'll get a runtime error. Now the following compiles as expected:
But if we add a new job type:
now it fails, also as expected:
The compiler error warns you that you haven't handled the new type, which should hopefully prompt you to add another
if/elsestatement.Playground link to code