GeezerVison is showing github.com — Infer from generic function return types by ahejlsberg · Pull Request #16072 · microsoft/TypeScript
Conversation
With this PR we improve type argument inference by inferring from the contextual type of a generic function call to the return type of the generic function. For example:
function emptyArray<T>(): T[] {
return [];
}
let a1: string[] = emptyArray(); // string inferred for T
let a2: number[] = emptyArray(); // number inferred for T
Previously the two assignments above would error because {} was inferred for T. We now infer from the contextual type (i.e. the type of the variable to which the function result is assigned).
A more elaborate example:
function arrayFilter<T>(f: (x: T) => boolean): (a: T[]) => T[] {
return a => a.filter(f);
}
function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[] {
return a => a.map(f);
}
function compose<A, B, C>(f: (x: A) => B, g: (x: B) => C): (x: A) => C {
return x => g(f(x));
}
const positives: (a: number[]) => number[] = arrayFilter(x => x >= 0);
const lengths: (a: string[]) => number[] = arrayMap(s => s.length);
const evenLengths: (a: string[]) => number[] =
compose(arrayMap(s => s.length), arrayFilter(x => x % 2 === 0));
let a1 = positives([1, 2, -3, 4, -5]); // [1, 2, 4]
let a2 = lengths(['a', 'bb', 'ccc', 'dddd']); // [1, 2, 3]
let a3 = evenLengths(['a', 'bb', 'ccc', 'dddd']); // [2, 4]
Inferences made from generic function return types have lower priority than inferences made from arguments to the generic function. For example, the type of s is inferred as string (not Object) in the following:
function filter<T>(a: T[], f: (x: T) => boolean): T[] {
return a.filter(f);
}
let a: Object[] = filter(['a', 'bb', 'ccc', 'dddd'], s => s.length > 2);
This PR is a precursor for inferring higher order function types when no inferences can be made for one or more type parameters.
const wrapper = compose(x => [x], y => ({ p: y })); // (x: {}) => { p: {}[] }
We currently infer (x: {}) => { p: {}[] }, but ideally we'd infer <A>(x: A) => { p: A[] }. That's next on the list.
Fixes #15680.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
abenhamdine, david-driscoll, stephenlaughton, KiaraGrouwstra, HerringtonDarkholme, alitaheri, Lenne231, dnavas77, arackaf, mohsen1, and 14 more reacted with thumbs up emoji
benlesh, BANG88, wand3r, yortus, JoshuaKGoldberg, aluanhaddad, zpdDG4gta8XKpMCd, maxdavidson, jquintozamora, adammedford, and 22 more reacted with hooray emoji
DanielRosenwasser, benlesh, trxcllnt, wand3r, alexrock, aluanhaddad, zpdDG4gta8XKpMCd, chasent, sean-vieira, david-driscoll, and 12 more reacted with heart emoji
All reactions
-
👍
24 reactions
-
🎉
32 reactions
-
❤️
22 reactions
|
I was told "if you get Anders interested in your typings issue, it'll be implemented in a few hours"
Apparently the legend is real.
|
DanielRosenwasser, BANG88, tinganho, wand3r, saschanaz, billba, JoshuaKGoldberg, aluanhaddad, danielyogel, sean-vieira, and 36 more reacted with laugh emoji
jwbay, s-panferov, otodockal, sean-vieira, KiaraGrouwstra, Igorbek, niieani, alitaheri, BrianMikinski, ErikCupal, and 4 more reacted with hooray emoji
All reactions
-
😄
46 reactions
-
🎉
14 reactions
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
// not contain anyFunctionType when we come back to this argument for its second round
|
|
|
// of inference.
|
|
|
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
|
|
|
if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worth adding a note on the use of silentNeverType as a marker here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
inferences.primary || (inferences.primary = []);
|
|
|
if (!contains(candidates, source)) {
|
|
|
candidates.push(source);
|
|
|
for (const inference of inferences) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getInferenceInfoForType here as well?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced May 27, 2017
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Why doesn't this fix #11152 ?
contextual type is not propagated/instantiated correctly yet.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Anders Hejlsberg (@ahejlsberg):
We currently infer (x: {}) => { p: {}[] }, but ideally we'd infer <A>(x: A) => { p: A[] }. That's next on the list.
If that's still outstanding, might there be any PR/branch we could follow on that?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Jun 27, 2017
contextual type is not propagated/instantiated correctly yet.
Mohamed Hegazy (@mhegazy) - I'm liking the use of the word "yet" above 👍 😄
|
jcjolley, mtpultz, and nateabele reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 15, 2017
|
Where can we track progress against the following bug?
type Function1<T1, R> = (t1: T1) => R
function pipe<T1, R>(fn: Function1<T1, R>): Function1<T1, R> {
return fn
}
/// test
function identity<A>(a: A): A { return a }
const pipedIdentity = pipe(identity)
// x is a {}, not a number
const x = pipedIdentity(33)
|
KiaraGrouwstra and nateabele reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
KiaraGrouwstra and AlexGalays reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
1 more reviewer
Reviewers whose approvals may not affect merge requirements
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|