Skip to content

Inverted union type narrowing was broken in 4.9Β #58861

Open
@Woodz

Description

@Woodz

πŸ”Ž Search Terms

"union type", "narrowing", "inverted", "4.9"

πŸ•— Version & Regression Information

⏯ Playground Link

Playground link

πŸ’» Code

interface Foo { foo: string; }

interface Bar { bar: string; }

interface Baz { baz: string; }

function myFunction(input: Foo | Bar | Baz) {
    const isBaz = 'baz' in input;
    const isBar = 
      //'bar' in input; // This works to narrow `bar` when true and narrow `foo` in the else block
      !('foo' in input) && !isBaz; // This works to narrow `bar` when true but does not narrow `foo` in the else block
    let x: string;
    if (isBaz) {
      x = input.baz;
    } else if (isBar) {
      x = input.bar;
    } else {
      // In 4.8.4 and earlier, `input` is narrowed to `Foo`
      // In 4.9.5 and later, `input` is narrowed to `Foo | ((Foo | Bar) & Record<"baz", unknown>)`
      x = input.foo;
    }
}

πŸ™ Actual behavior

In 4.9.5 and later, in the else block, input.foo incorrectly narrows and errors

πŸ™‚ Expected behavior

In 4.8.4 and earlier, in the else block, input.foo correctly narrows

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions