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

Contextual typing based on instantiated types #30568

Merged
merged 6 commits into from
Mar 28, 2019

Conversation

ahejlsberg
Copy link
Member

@ahejlsberg ahejlsberg commented Mar 24, 2019

With this PR we improve our ability to contextually type parameters of arrow functions and function expressions passed as arguments, allowing contextual types to depend on inferences made from other arguments. For example:

type EventMap = {
  a: () => void,
  b: (x: number, y: number) => number;
  c: (s: string) => boolean;
}

type EventObject = {
  on<K extends keyof EventMap>(key: K, handler: EventMap[K]): ReturnType<EventMap[K]>;
}

declare var obj: EventObject;
obj.on('a', () => {});            // () => void
obj.on('b', (x, y) => x * y);     // (x: number, y: number) => number
obj.on('c', s => s.length > 10);  // (s: string) => boolean

Above, the contextual type for each arrow function arguments depends on the type inferred for K from the first argument. Specifically, the contextual type for the arrow function argument is instantiated with inferences made from other arguments before the contextual type is applied to the arrow function parameters.

Fixes #6611.
Fixes #21382.
Fixes #22149.
Fixes #25299.
Fixes #25759.
Fixes #25814.
Fixes #29775.
Fixes #30341.

@ahejlsberg
Copy link
Member Author

@typescript-bot test this.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 24, 2019

Heya @ahejlsberg, I've started to run the extended test suite on this PR at de76d55. 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 Mar 24, 2019

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

@ahejlsberg
Copy link
Member Author

The RWC tests are clean. The DT tests have a few changes that are to be expected: Now, when type inference produces no candidates and a type parameter has no explicit default, we consistently default to the constraint of the type parameter. Previously we'd default to {} if {} was assignable to the constraint. For example, we'd default to {} when the constraint is object.

@DanielRosenwasser
Copy link
Member

type EventMap = {
  a: () => void,
  b: (x: number, y: number) => number;
  c: (s: string) => boolean;
}

type EventObject = {
  on<K extends keyof EventMap>(key: K, handler: EventMap[K]): ReturnType<EventMap[K]>;
}

declare var obj: EventObject;
obj.on('a', () => {});            // () => void
obj.on('b', (x, y) => x * y);     // (x: number, y: number) => number
obj.on('c', s => s.length > 10);  // (s: string) => boolean

The only example that doesn't work right now is the call to obj.on('c', ...), where you'll get an implicit any error:

Parameter 's' implicitly has an 'any' type.

Why does the call to on('b', ...) work as desired?

@ahejlsberg
Copy link
Member Author

Why does the call to on('b', ...) work as desired?

We do some rudimentary signature filtering based on arity and since there is only one signature with arity two or greater we were able to produce a contextual signature for the b case.

@ahejlsberg ahejlsberg merged commit c03b7f5 into master Mar 28, 2019
@ahejlsberg ahejlsberg deleted the instantiateContextualTypes branch March 28, 2019 19:38
sandersn added a commit to DefinitelyTyped/DefinitelyTyped that referenced this pull request Mar 29, 2019
pull bot pushed a commit to 9renpoto/DefinitelyTyped that referenced this pull request Mar 29, 2019
* Update for microsoft/TypeScript#30568

* Use assignability instead of ExpectType

Since assignability allows subtype relations
alesn pushed a commit to alesn/DefinitelyTyped that referenced this pull request Apr 23, 2019
* Update for microsoft/TypeScript#30568

* Use assignability instead of ExpectType

Since assignability allows subtype relations
sandersn added a commit to DefinitelyTyped/DefinitelyTyped that referenced this pull request Apr 30, 2019
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.

5 participants