```ts // #-------------- This works type Repeat = (n: number) => (s: string) => string; export const repeat: Repeat = n => s => s.repeat(n); // Sweet! s and n are both inferred! // -------------------------# // #----- Problems begin here type Repeat2 = (n: number) => <T extends { repeat(n: number): T }>(repeatable: T) => T; // Only n is inferred as number. Won't work with noImplicitAny enabled export const repeat2Broken: Repeat2 = n => r => r.repeat(n); // Workaround is to redeclare everything from the type signature export const repeat2Ugly: Repeat2 = n => <T extends { 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 inference type Repeat3 = (n: number) => <T extends { 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 enabled export const repeat3UglyAndBroken: Repeat3 = n => <T extends { repeat(n: number): T }>(r: T) => b => { ... } // You have to add typing for the last arg export const repeat3Uglier: Repeat3 = n => <T extends { 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: ```ts export type GetState<TState> = () => TState; export type SetState<TState> = (newState: TState) => void; export type StatelessComponent<TProp> = (prop: TProp) => React.ReactElement<TProp> export type StatefulComponent<TProp, TState> = (stateAccess: { getState: GetState<TState>, setState: SetState<TState> }) => StatelessComponent<TProp>; type ScrollableHOC = (options: ScrollableOptions) => <T extends ScrollableProps>(Child: ReactComponent<T>) => StatefulComponent<T, ScrollableState>; // The introduction of the Child arg breaks type inference for getState, setState, props const scrollable: ScrollableHOC = opts => Child => ({ getState, setState }) => props => { // ... } ```