Skip to content

Optional chaining does not narrow types in the else branch  #42480

@kdmadej

Description

@kdmadej

Bug Report

🔎 Search Terms

  • optional chaining
  • optional chaining narrow
  • optional chaining discriminated

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about:
    • optional chaining
    • type narrowing

Tested on all TS versions available in the playground that support optional chaining.
At the time of writing:

  • 4.2.0-beta
  • 4.1.3
  • 4.0.5
  • 3.9.7
  • 3.8.3
  • 3.7.5

⏯ Playground Link

Playground link with relevant code

💻 Code

type A = { type: 'A', a: 'a' }
type B = { type: 'B', b: 'b' }

declare const c: A | B | null
// declare const c: A | B | undefined
// declare const c: A | B // works fine for non-nullable unions

if (c?.type === 'A') {
    c; // narrowed to `A` as expected
} else {
    c; // `A` still present in the type
}

🙁 Actual behavior

In the second branch of the conditional statement the union type inferred for c still includes A. Same thing happens with ternary operator, functions with early returns, etc.

🙂 Expected behavior

In the second branch the type should be narrowed down by excluding A.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions