You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// #-------------- This workstypeRepeat=(n: number)=>(s: string)=>string;exportconstrepeat: Repeat=n=>s=>s.repeat(n);// Sweet! s and n are both inferred!// -------------------------#// #----- Problems begin heretypeRepeat2=(n: number)=><Textends{repeat(n: number): T}>(repeatable: T)=>T;// Only n is inferred as number. Won't work with noImplicitAny enabledexportconstrepeat2Broken: Repeat2=n=>r=>r.repeat(n);// Workaround is to redeclare everything from the type signatureexportconstrepeat2Ugly: Repeat2=n=><Textends{repeat(n: number): T}>(r: T)=>r.repeat(n);// -------------------------#// #----------- It gets worse// Type inference breaks for all args following the generic one, so even if you use// the workaround, the next args won't regain inferencetypeRepeat3=(n: number)=><Textends{repeat(n: number): T}>(repeatable: T)=>(reverse: boolean)=>T;// Even if you explicitly provide the boilerplate for the generic arg, the boolean arg // won't be inferred. So the following won't work with noImplicitAny enabledexportconstrepeat3UglyAndBroken: Repeat3=n=><Textends{repeat(n: number): T}>(r: T)=>b=>{ ... }// You have to add typing for the last argexportconstrepeat3Uglier: Repeat3=n=><Textends{repeat(n: number): T}>(r: T)=>(b: boolean)=>{ ... }// -------------------------#
I'd really appreciate better support for good inference in this kind of scenario, whether it is solved by supporting partial generic application or addition of participation of return-types in inference or whatever.
JS libraries that use a functional programming paradigm often end up loosely or any-ly typed, because you find yourself fighting the type system and adding repetitive type noise all over your code to derive any safety. A couple of examples where better support for FP would be useful:
Libraries like React or Apollo make use of curried higher-order functions for solving cross-cutting concerns. In-fact, my original use case comes from React higher-order components
Popular FP libraries like Ramda become tedious to use in a noImplicitAny project because any generic functions passed or received from the library tend to quickly devolve into {} unless you repeatedly hand-hold the type system
Here is my original use-case, if interested:
exporttypeGetState<TState>=()=>TState;exporttypeSetState<TState>=(newState: TState)=>void;exporttypeStatelessComponent<TProp>=(prop: TProp)=>React.ReactElement<TProp>exporttypeStatefulComponent<TProp,TState>=(stateAccess: {getState: GetState<TState>,setState: SetState<TState>})=>StatelessComponent<TProp>;typeScrollableHOC=(options: ScrollableOptions)=><TextendsScrollableProps>(Child: ReactComponent<T>)=>StatefulComponent<T,ScrollableState>;// The introduction of the Child arg breaks type inference for getState, setState, propsconstscrollable: ScrollableHOC=opts=>Child=>({ getState, setState })=>props=>{// ...}
I'd really appreciate better support for good inference in this kind of scenario, whether it is solved by supporting partial generic application or addition of participation of return-types in inference or whatever.
JS libraries that use a functional programming paradigm often end up loosely or any-ly typed, because you find yourself fighting the type system and adding repetitive type noise all over your code to derive any safety. A couple of examples where better support for FP would be useful:
noImplicitAnyproject because any generic functions passed or received from the library tend to quickly devolve into{}unless you repeatedly hand-hold the type systemHere is my original use-case, if interested: