Skip to content
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

Improve type inference for types like 'T | Promise<T>' #32460

Merged
merged 19 commits into from
Jul 23, 2019
Merged

Conversation

ahejlsberg
Copy link
Member

@ahejlsberg ahejlsberg commented Jul 17, 2019

This PR improves type inference to union types that contain combinations of nested and naked type variables. Previously, we'd always give lower priority to inferences made to naked type variables in union types, but this produced sub-optimal results in some fairly basic scenarios (see #32434).

The improved algorithm for inferring from a single source type or a union of source types to a target union type is:

  • First, infer from each source type to each target type that isn't a naked type parameter, tracking for each source whether any inferences are made from that type.
  • Second, if there are source types from which no inferences were made in the first step, infer from a union of those source types to each naked type parameter in the target type. Give lower priority to these inferences only if the target contains more than one naked type parameter.

Some examples:

declare function foo<T>(x: T | Promise<T>): T;
declare let x: false | Promise<true>;
const y = foo(x);  // boolean

declare function bar<T>(x: T, y: string | T): T;
const z = bar(1, 2);  // 1 | 2

Previously both of the examples above caused errors.

This PR also fixes an inconsistency we've long had.

declare function baz1<T>(x: T | string): T;
declare const s: string;
const x1 = baz1(s);  // Was string, now unknown

declare function baz2<T>(x: T | string | number): T;
declare const sn: string | number;
const x2 = baz2(sn);  // Was never, now unknown

We now infer unknown for T in both cases above (because there is nothing left to infer from when the matching types are eliminated, and T has no constraint or default).

Fixes #32434.

@ahejlsberg ahejlsberg added this to the TypeScript 3.6.0 milestone Jul 17, 2019
@ahejlsberg
Copy link
Member Author

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 17, 2019

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 17, 2019

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

@ahejlsberg
Copy link
Member Author

Latest commit fixes an issue where strangely we infer nothing for T in

declare function flatten<T>(array: ReadonlyArray<ReadonlyArray<T>>): T[];
declare let naa: number[][];
let na = flatten(naa);

Before the commit, na would have type unknown[]. We currently limit inference between two types with the same symbol to a single level, which causes the issue. This is fixed by #31633, but meanwhile this commit is takes care of the issue for array types.

@ahejlsberg
Copy link
Member Author

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 18, 2019

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 18, 2019

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

@timsuchanek
Copy link
Contributor

@ahejlsberg you're probably very busy, but in case you find the time, it would be great if you could have a look at #32100 🙏

@ahejlsberg
Copy link
Member Author

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 20, 2019

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 20, 2019

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

@ahejlsberg
Copy link
Member Author

RWC tests look good. Only one change in vscode, an error that shouldn't be is now gone.

@ahejlsberg
Copy link
Member Author

@typescript-bot run dt

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 20, 2019

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

@ahejlsberg
Copy link
Member Author

@typescript-bot run dt

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 21, 2019

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

@ahejlsberg
Copy link
Member Author

@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 22, 2019

Heya @ahejlsberg, I've started to run the parallelized community code test suite on this PR at 203fd9f. 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

Verified that user test suite differences are all preexisting conditions.

@ahejlsberg
Copy link
Member Author

@typescript-bot run dt

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jul 23, 2019

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

@ahejlsberg
Copy link
Member Author

Two minor issues in DT tests are covered by DefinitelyTyped/DefinitelyTyped/pull/37057.

@ahejlsberg
Copy link
Member Author

Merging this now. There are a few breaks in the RWC suites that I have reviewed with @RyanCavanaugh.

@ahejlsberg ahejlsberg merged commit 9ec71c3 into master Jul 23, 2019
@weswigham
Copy link
Member

I think this is significantly affecting vscode - there's no diff in the user PR because output is completely blocked by an issue during build (so the test outright fails with no diff) - microsoft/vscode#77835 should resolve that, as it's just a lingering affect of some old generator type definitions. Once that's in place, though, vscode has many new errors:
image

@weswigham
Copy link
Member

Scratch that, it might be the node version bump itself that's breaking so much; or at least a fair part of it.

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.

Suboptimal inference to unions like T | Promise<T>
5 participants