-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect post-narrowing merge of typeof symbol | {} | (() => void)
#45467
Comments
More like it gave up on keeping union and used Because everything from that union is assignable to const symbol = Symbol("Test");
// no errors
const x1: 1 | "a" | typeof symbol | {} | (() => void) = 123;
const x2: 1 | "a" | typeof symbol | {} | (() => void) = "not a";
const x3: 1 | "a" | typeof symbol | {} | (() => void) = Symbol("not Test");
const x4: 1 | "a" | typeof symbol | {} | (() => void) = (a: number) => a;
// no errors
const y1: {} = 1;
const y2: {} = "a";
const y3: {} = Symbol("a");
const y4: {} = () => {};
// errors as expected
const z1: 1 | "a" | typeof symbol | (() => void) = 123;
const z2: 1 | "a" | typeof symbol | (() => void) = "not a";
const z3: 1 | "a" | typeof symbol | (() => void) = Symbol("not Test");
const z4: 1 | "a" | typeof symbol | (() => void) = (a: number) => a; Not sure about your use case but |
Simpler repro const symbol = Symbol("Test");
function f(x: typeof symbol | {} | (() => void)): void {
if (typeof x === "function") { }
x;
} These issues happen when the re-unioning logic gets messed up when merging the two incoming control flow edges. But there's not much reason to write this code in first place. |
typeof symbol | {} | (() => void)
This looks like subtype reduction, similar to what happens in #39434. |
@RyanCavanaugh @jakebailey should this still be classified as a bug? the weird behavior with multiple switch cases from the OP was already "fixed" by #49119 . As Ryan's answer suggests - this is just union reduction at play when merging control flow paths. I don't exactly see this particular example to be a good motivation for reconsidering the used algorithm. |
I think ideally we would still go back to the declared type -- you could imagine an algorithm that detects that all incoming paths have an uninterrupted flow from the origin and does this -- but yeah, this isn't wrong per our normal stance of "subtype reduction can occur at any time". |
Bug Report
π Search Terms
switch incorrectly narrows type
π Version & Regression Information
v4.3.5
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
Starting from 4th switch the type of x is narrowed to {}.
π Expected behavior
The type of x should not be narrowed
The text was updated successfully, but these errors were encountered: