Skip to content

Contextually typed binding element initializers #35855

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

Merged
merged 5 commits into from
Jan 6, 2020
Merged

Contextually typed binding element initializers #35855

merged 5 commits into from
Jan 6, 2020

Conversation

ahejlsberg
Copy link
Member

@ahejlsberg ahejlsberg commented Dec 25, 2019

This PR revises our contextual typing logic for initializers in destructuring declarations. Previously, the construct

let { a = xxx } = b;

had no contextual type for xxx. Now, xxx is contextually typed by b.a and the type inferred for a is consistent with the logically equivalent

let a = b.a ?? xxx;

with the exception that ?? substitutes xxx for both undefined and null whereas destructuring has no special behavior for null.

Some examples:

declare let x: { a: 0 | 1 | undefined };

let { a: a1 } = x;               // 0 | 1 | undefined
let { a: a2 = 0 } = x;           // 0 | 1
let { a: a3 = 2 } = x;           // number
let { a: a4 = 2 as const } = x;  // 0 | 1 | 2

Before this PR, the inferred type for a2 was number. Now, because the type of the initializer is a subtype of the contextual type 0 | 1 | undefined, no widening occurs. However, an initial value of 2 causes widening because it isn't a subtype. If this widening is not desired, a const assertion can be used to suppress it.

Fixes #35693.

@ahejlsberg
Copy link
Member Author

@typescript-bot test this
@typescript-bot user test this
@typescript-bot run dt

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 25, 2019

Heya @ahejlsberg, I've started to run the parallelized community code test suite on this PR at 529afa9. You can monitor the build here. It should now contribute to this PR's status checks.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 25, 2019

Heya @ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at 529afa9. You can monitor the build here. It should now contribute to this PR's status checks.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 25, 2019

Heya @ahejlsberg, I've started to run the extended test suite on this PR at 529afa9. You can monitor the build here. It should now contribute to this PR's status checks.

@typescript-bot
Copy link
Collaborator

The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master.

@ahejlsberg
Copy link
Member Author

@typescript-bot run dt
@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 29, 2019

Heya @ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at f986e16. You can monitor the build here. It should now contribute to this PR's status checks.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 29, 2019

Heya @ahejlsberg, I've started to run the parallelized community code test suite on this PR at f986e16. You can monitor the build here. It should now contribute to this PR's status checks.

@typescript-bot
Copy link
Collaborator

The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master.

@ahejlsberg
Copy link
Member Author

RWC tests are clean. DT and Community test failures all appear to be preexisting conditions.

@ahejlsberg
Copy link
Member Author

@RyanCavanaugh @weswigham This one is ready to merge. Want to take a look?

Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm: we no longer need to specially handle the widening of binding patterns whose initializer is an assertion expression because... our assumption is assertions can't occur in JS files? (/* @type */ casts should probably have counted though, even though they didn't) Or for another reason?

@ahejlsberg
Copy link
Member Author

@weswigham The special case for a type assertion predated our support for fresh literal types. It was there just so you could force a binding element declaration not to widen. We neither need nor want that odd behavior anymore. Widening now follows naturally from the combined freshness of the destructured element type and the initializer type, i.e. a unit type stays fresh only of every occurrence of it in a union type is fresh.

@ahejlsberg ahejlsberg merged commit f8bfc6f into master Jan 6, 2020
@jakebailey jakebailey deleted the fix35693 branch November 7, 2022 17:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Destructuring an optional property with union containing literal type should not be widen if the default value is compatible with the union
4 participants