Typescript - Remove last element from Parameters tuple, currying away last argument

Viewed 1203

I want to do currying with typescript and have:


const findValueInDb = (value: number, dbSpec: string) => `found it, it's here: ${dbSpec}!`

const createFindValue = (dbSpec: string) =>
    (...params: Omit<Parameters<typeof findValueInDb>, "1">) => findValueInDb(...params, dbSpec)

const theResult = createFindValue("theDb")(10)

This does not work, and it would not be very flexible if arguments are added to the source function. How can I define a currying contract? One that removes the last argument, but keeps the others?

1 Answers

In TypeScript 4 you can use an inferred tuple type to get all elements except the last (or first, etc.):

type Head<T extends any[]> = T extends [ ...infer Head, any ] ? Head : any[];
const findValueInDb = (value: number, dbSpec: string) => `found it, it's here: ${dbSpec}!`

const createFindValue = (dbSpec: string) =>
    (...params: Head<Parameters<typeof findValueInDb>>) => findValueInDb(...params, dbSpec)

const findValue = createFindValue("theDb")(10)

Playground Link

Related