Skip to content

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
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants