Uh oh!
There was an error while loading. Please reload this page.
Support higher order inferences for constructor functions - #31116
Conversation
Anders Hejlsberg (ahejlsberg)
commented
Apr 25, 2019
TypeScript Bot (@typescript-bot) test this |
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the extended test suite on this PR at fcd6f52. You can monitor the build here. It should now contribute to this PR's status checks. |
Anders Hejlsberg (ahejlsberg)
commented
Apr 25, 2019
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at fcd6f52. You can monitor the build here. It should now contribute to this PR's status checks. |
Anders Hejlsberg (ahejlsberg)
commented
Apr 25, 2019
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 4fe59dc. You can monitor the build here. It should now contribute to this PR's status checks. |
Wesley Wigham (weswigham)
commented
Apr 25, 2019
The |
Anders Hejlsberg (ahejlsberg)
commented
Apr 26, 2019
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 3e79e8d. You can monitor the build here. It should now contribute to this PR's status checks. |
Hi Ryan Cavanaugh (@RyanCavanaugh)Anders Hejlsberg (@ahejlsberg), Please find below an adapted example from the one in this PR: declareclassPoint{constructor(x: number,y: number)readonlyx: numberreadonlyy: number}declareclassBag<T>{constructor(...args: T[])contains(value: T): booleanstaticfoo: string}functionasFunction<Aextendsany[],B>(cf: new(...args: A)=>B){return(...args: A)=>newcf(...args)}constnewPoint=asFunction(Point)// (x: number, y: number) => PointconstnewBag=asFunction(Bag)// <T>(...args: T[]) => Bag<T>constp1=newPoint(10,20)// Pointconstp2=newPoint(10,20)// Pointconstbag1=newBag(1,2,3)// Bag<number>constbag2=newBag('a','b','c')// Bag<string>declareclassComponent<P>{props: Pconstructor(props: P)}interfaceComponentClass<P>{new(props: P): Component<P>thisWillBreakGenericInference?: boolean// <--- this is breaking the type inference}declarefunctionmyHoc<P>(C: ComponentClass<P>): ComponentClass<P>typeGenericProps<T>={foo: number;stuff: T}declareclassGenericComponent<T>extendsComponent<GenericProps<T>>{}// Should be:// const GenericComponent2: new <T>(props: GenericProps<T>) => Component<GenericProps<T>>// Actually: // const GenericComponent2: ComponentClass<GenericProps<unknown>>constGenericComponent2=myHoc(GenericComponent)Link to playground: The issue here is that React's ComponentClass interface has a few optional members defined. |
Anders Hejlsberg (ahejlsberg)
commented
Jun 18, 2019
@guykr-stratoscale That's a known limitation. See discussion in #30650 (comment). |
Jeanette Vang (RichardForrester)
commented
Jul 21, 2019
It's really encouraging that TS is getting some more support for functional programmers. Keep up the good work! Small critique on the announcement docs. The function you guys are showing off as functioncompose<T,U,V>(f: (x: T)=>U,g: (y: U)=>V): (x: T)=>V{returnx=>g(f(x))}Based on all of the below resources: -- Haskell(.):: (b->c) -> (a->b) ->a->c// Sanctuary.js
compose :: Semigroupoids=>sbc->sab->sac// fp-tsexportinterfaceSemigroupoid<F>{readonlyURI: Freadonlycompose: <E,A,B>(ab: HKT2<F,A,B>,la: HKT2<F,E,A>)=>HKT2<F,E,B>}// Ramda(b->c)->(a->b)->a->c// CrockscomposeB :: (b->c)->(a->b)->a->cI understand the the announcement docs are just for simple illustration, and it's great. I'm thrilled about the attention to the functional side of javascript. But it would be nice to have simple and correct code for the docs, maybe something like: typefn1<I,O>=(i: I)=>Otypecompose=<Textendsany,U,V>(f: fn1<U,V>)=>(g: fn1<T,U>)=>fn1<T,V>constcompose: compose=f=>g=>a=>f(g(a)) |
This PR expands on #30215 to support higher order inferences for constructor functions and to permit function type arguments to higher order composition functions to have other members in addition to their single call signature.
Some examples:
The rules for determining when higher order inferences occur are revised as follows. Given a generic function
fof type<…>(…, x: P, …) => R, and an argument expressionaof a generic function typeA, in a call expressionf(…, a, …)the type parameters ofAare propagated onto the inferred result type of the function call if:Pis a function type with no type arguments, a single call or construct signature, and no other members, andRis a function type with no type arguments, a single call or construct signature, and no other members, andAis function type with type arguments and a single call or construct signature that matchesP(note thatAis permitted to have other members), andP.Fixes#30650.