Narrow destructured discriminated unions when the discriminant has a default#63563
Conversation
A default on a required discriminant binding no longer disables discriminant narrowing of the sibling bindings. The default is ignored for narrowing only when it can never apply (the property is present and non-undefined in every union constituent), so optional or possibly-undefined discriminants keep their previous sound behavior. Fixes microsoft#50139
|
This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise. |
1 similar comment
|
This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise. |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a regression test and compiler fix to ensure discriminant narrowing still works when a required discriminant is destructured with a default initializer, while preserving existing soundness boundaries for optional/possibly-undefined discriminants.
Changes:
- Added a new conformance test covering narrowing behavior with required discriminants that have destructuring defaults (plus negative/soundness cases).
- Updated
checker.tsto allow dependent narrowing through binding elements with defaults only when the default can never apply (property always present and non-undefinedacross the declared union). - Added corresponding reference baselines (
.types,.symbols,.errors.txt) for the new test.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/cases/conformance/controlFlow/dependentDestructuredVariablesWithDefaults.ts | New regression test validating narrowing with required discriminants + defaults and guarding soundness boundaries. |
| tests/baselines/reference/dependentDestructuredVariablesWithDefaults.types | Baseline updated to reflect the new test’s expected type/narrowing results. |
| tests/baselines/reference/dependentDestructuredVariablesWithDefaults.symbols | Baseline updated to reflect expected symbol binding results for the new test. |
| tests/baselines/reference/dependentDestructuredVariablesWithDefaults.errors.txt | Baseline updated to capture expected errors for unsound narrowing cases. |
| src/compiler/checker.ts | Compiler change enabling dependent narrowing through destructured defaults when the default is provably never used. |
|
The TypeScript repo is closed for development; PR should be in the typescript-go repo. Please see the top section of CONTRIBUTING.md and pinned issue #62963. |
A default on the discriminant of a destructured union disables narrowing for the sibling bindings -
{ isText = false, children }: Propsleaveschildrenasstring | numberin both branches. It now still narrows when the default can never fire (the property is required and non-undefined across the union). Optional or possibly-undefined discriminants, and siblings with their own default, stay unchanged. Added a conformance test covering both.Fixes #50139