Closed
Description
Bug Report
🔎 Search Terms
narrow non-union never
narrow record never
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about "narrow" and "never".
(I tested on the Playground with v3.3.3333, v4.0.5, v4.6.0-dev.20211201.)
⏯ Playground Link
Playground link with relevant code
💻 Code
export function impossible(_value: never): never {
throw new Error('impossible! (according to static types)');
}
// This is how we define errors for some of our operations.
export type Operation1Error =
| {type: 'not_found'}
| {type: 'not_authorized', details: string};
// We use this pattern to handle errors. If someone adds a new option to
// Operation1Error, TS will tell us we need another branch.
function f1(err: Operation1Error): void {
if (err.type === 'not_found') {
// ...
} else if (err.type === 'not_authorized') {
// ...
} else {
throw impossible(err);
}
}
// Some of our operations currently have just a single type of error.
export type Operation2Error =
| {type: 'not_found'}
// This doesn't work as well -- TS doesn't allow us to use the same pattern.
function f2(err: Operation2Error): void {
if (err.type === 'not_found') {
// ...
} else {
// TS error: Argument of type '{ type: "not_found"; }' is not assignable to parameter of type 'never'.
throw impossible(err);
}
}
🙁 Actual behavior
In f2
, I get a type error on impossible(err)
. (See comment in code sample.)
🙂 Expected behavior
In f2
, I was hoping that err
gets narrowed to never
and I don't get a type error when using impossible(err)
.