Lodash Flow and TypeScript Lodash Flow and TypeScript typescript typescript

Lodash Flow and TypeScript


As JavaScript/TypeScript is interpreted (note: The TypeScript code is transpiled to JavaScript which is then interpreted), when you use chain, typescript is aware of the type its dealing with (i.e. an array of numbers) as its comes first. However with flow, the type the flow functions are going to act on is specified last so it doesn't know what types it's going to use, hence the need of generics or another way of indicating the types that are going to be used. Also the linter generating this error is interpreting the code, so it doesn't know the types being dealt with when the input comes last when using "flow".

As you are using lodash with TypeScript, the functions you are using support generics to specify the types they are dealing with.

Hence you can state what is being inputted/outputted from the lodash functions as follows:

flow(    map<number, [number, number]>(x => [x, x * 2]),    flatten,    sortBy(x => x))([1, 2, 3]);

or as dareka suggests:

flow(    map((x: number) => [x, x * 2]),    flatten,    sortBy(x => x))([1, 2, 3])

But again this only works because we are indicating to the compiler what the type is that is going to be acted on.

An example of these code snippets working can be found here.

Note how the function inputs/outputs have been explicitly defined e.g. "map" indicates that the type it is going to iterate over is a number, and the result of the operation is a tuple.


The _.flow() method generates a pointfree function. This prevents typescript from inferring the type of the input.

To solve this, assign the function to a variable, and add the function's type. When the functions parameters and the output are declared, typescript can infer the internal types of the functions inside flow.

After assigning the function to a variable, you can call it (sandobx):

const fn: (numbers: number[]) => number[] = flow(    map(x => [x, x*2]),    flatten,    sortBy(x => x) );const result = fn([1,2,3]);

Or use type assertion if you want to invoke the function immediately (sandbox):

type Fn = (numbers: number[]) => number[];const result = (flow(  map(x => [x, x * 2]),  flatten,  sortBy(x => x)) as Fn)([1, 2, 3]);


I like Ben Smith's answer as it was quite educational for me. But I was going to suggest this

map((x: number) => [x, x*2])

or even

map((x: any) => [x, x*2])

for more general cases. It seems working and will get as much inference as possible if you don't want to be too strict.