-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Description
Bug Report
🔎 Search Terms
control flow analysis
function overrides
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about it.
- I discovered it on 4.0.7 and verified on 4.0.5 and 4.4.4
⏯ Playground Link
Playground link with relevant code
💻 Code
const nonempty: Function = (s: string) => s.length != 0;
function assert(cond: boolean, msg: string) : void;
function assert(cond: false, msg: string) : never;
function assert(cond: boolean, msg: string) {
if (!cond) throw new Error(msg);
}
const d = nonempty("foo");
assert(d, "hi");
for (const x of ["a", "b", "c"]) {
nonempty("bar");
}🙁 Actual behavior
nonempty is narrowed to never after the assert()
The for loop is labeled as unreachable code in the typescript playground (but not by tsc - going to file that as a separate issue)
It appears that typing nonempty as a Function makes the return any, and that doesn't match the right overload of assert - for whatever reason it always matches the assert(cond: false, msg:string) case which returns never and therefore concludes, erroneously, that the rest of the code is unreachable.
🙂 Expected behavior
expect no errors - the assert(cond: boolean, msg: string): void signature should match and so typescript should not be able to assume code after the assert() call is unreachable. Perhaps the typesafe way to do this would be unioning all the possible return types.
Edit by @sandersn: See #46376 (comment) for a smaller repro