GeezerVison is showing github.com — Supporting generic type inference over the other higher-order functions · Issue #9366 · microsoft/TypeScript
Supporting generic type inference over the other higher-order functions #9366DescriptionCurrently, TypeScript infers generic types when referring its type immediately. Its behavior is undesirable for using higher-order functions. The type inference of generics should delay until it will be called.
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
return (b: b, a: a) => f(a, b);
}
function zip<T, U>(x: T, y: U): [T, U] {
return [x, y];
}
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
var actual: (y: {}, x: {}) => [{}, {}] = flip(zip);Reacted by Aluan Haddad, Adam Schroder, Sergey Shandar, Marin Marinov, François de Campredon, Dylan Schiemann, Dave Wasmer, Sean Newell, ZpdDG4gta, Zoey and 115 more Reacted by Cristian Toma, Dylan Schiemann, ZpdDG4gta, Zoey, Emma, Erik Cupal, Dylan R. Johnston, Roy Tinker, Alexandre Galays, Daniel Popeski and 34 more Activityfdecampredon commented on Dec 14, 2016 this issue is really problematic for functional paradigm users :
const map = <T, U>(transform: (t: T) => U) =>
(arr: T[]) => arr.map(transform)
const identity = <T>(t: T) => t;
const identityStr = (t: string) => t;
const arr: string[] = map(identityStr)(['a']);
const arr1: string[] = map(identity)(['a']); // Type '{}[]' is not assignable to type 'string[]'.Reacted by Herrington Darkholme, Andrea Richiardi, Zoey, Daniel Yogel, Anders Hejlsberg, Will Frew, Thierry Régagnon, Erik Cupal, Roy Tinker, Daniel Popeski and 21 more DanielRosenwasser commented on Dec 15, 2016 Reacted by Mohamed Hegazy, kiara, Erik Cupal, Daniel Popeski and Tycho Tatitscheff Reacted by Mohamed Hegazy, Ryan Cavanaugh, Erik Cupal, Daniel Popeski and Acid Chicken fdecampredon commented on Dec 15, 2016 baio commented on Jan 19, 2017 Yep, there is to many <any> in my Ramda code. Igorbek commented on Feb 21, 2017 masaeedu commented on Jul 31, 2017 Relevant paper: "Practical type inference for higher-rank types". Specifically the section on subsumption of parametrically polymorphic signatures.
Ultimately this comes down to better unification, which is what Marin Marinov (@gcnew) has done some work on if you follow along in #9949. For the flip example above, the rank 1 function type <T, U>(x: T, y: U) => [T, U] can be substituted for the rank 0 function type (a: a) => (b: b) => c to obtain f: (x: a, y: b) => [a, b], because the former is more polymorphic than the latter. From there we need TypeScript's usual approach to unification to kick in and infer c = [a, b]. The tricky part is coming up with a general algorithm to do all of this. Reacted by Roy Tinker, Daniel Popeski, Cameron Martin, Nate Abele, James Conkling, Abraham White and FTS pelotom commented on Nov 6, 2017 Another example:
const compose = <A, B, C>(g: (b: B) => C, f: (a: A) => B) => (a: A) => g(f(a))
const identity = <T>(x: T) => x
const lessThanTen = (x: number) => x < 10
const composed = compose(lessThanTen, identity)
// ^^^^^^^^^^^
// Argument of type '(x: number) => boolean' is not assignable to parameter of type '(b: {}) => boolean'.
// Types of parameters 'x' and 'b' are incompatible.
// Type '{}' is not assignable to type 'number'.
Can be fixed with explicit type parameters
const composed = compose<number, number, boolean>(lessThanTen, identity)
but would be really nice if this could just unify! Birowsky commented on Dec 22, 2017 Reacted by Igor Soloydenko cameron-martin commented on Mar 5, 2018 I've ran into this issue when using lodash's memoize function when the function being memoised is generic. steve8708 commented on May 3, 2018 This would also be really valuable for mixins on react components with proptypes
export class MyComponent extends MyMixin(React.Component<MyComponentProps>) {}
I love the new mixins feature since 2.2 and I was really excited about refactoring my code to create a variety of mixins for my components until I realized as of right now it won't quite work as I'd hoped without a lot of manual type declaring 😭 kpdonn commented on Jun 2, 2018 Heads up I put up my attempt at implementing this at #24626. No idea if it'll go anywhere but it works for a lot of the cases I've tried so feel free to try it out if you're interested. Reacted by Milos Nedeljkovic, Daniel Popeski, Aaron Friel, kiara, deepalma, Bastian Sieker, Oliver Joseph Ash, Marin Marinov, falsandtru, Alex Fox Gill and 5 more Reacted by falsandtru, Josh Burgess and Nate Abele nateabele commented on Jun 2, 2018 Reacted by Kevin Donnelly, kiara, deepalma, Joshua Weiss, Josh Burgess and James Conkling sibelius commented on Jul 20, 2018 Reacted by Jiali Chen, Axel Hernández Ferrera, Martin Kock, Abraham White, Evan Carroll, MattiasMartens, Nate Abele, Ricky Rattlesnake, Giacomo Tagliabue and Joni Katajamäki ahejlsberg commented on Mar 4, 2019 Higher order function type inference now implemented in #30215. Reacted by Stéphane Le Dorze, James Conkling, Nate Abele, John Reilly, kiara, Sergey, Lucas Basquerotto, Derrick Beining, Brett Larson, SlurpTheo and 18 more Reacted by Nate Abele, John Reilly, kiara, Derrick Beining, malinin, Igor Soloydenko, Joshua Weiss, kristianhasselknippe, Anders Bech Mellson, Jules Sam. Randolph and 5 more Reacted by John Reilly, kiara, Alex Ketch, Derrick Beining, Igor Soloydenko, Joshua Weiss, kristianhasselknippe, Jules Sam. Randolph, Changsheng Zhu and Janek Eilts UG (haftungsbeschränkt) Reacted by Stéphane Le Dorze, Nate Abele, John Reilly, kiara, btoo, Derrick Beining, malinin, Igor Soloydenko, Joshua Weiss, kristianhasselknippe and 4 more
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|