Partial generic type inference in Typescript [duplicate]

I am stumped by this and cannot figure out how to do this without a second function:

interface Fixed { a: number }
const fn = <A, B extends {} = {}>(b: B) => {
  return b
}

fn({ a: 1 }) // { a: number }
fn<Fixed>({ a: 1 }) // {}

const fn2 = <A>() => <B extends {} = {}>(b: B) => {
  return b
}

const result = fn2<Fixed>()({ a: 1 }) // { a: number }

Why does Typescript not infer the type of B if I fix type A? If I return a function that in turn tries to infer the type of B everything works again.


Type inference works based on an all or nothing principle. In the first case:

fn({ a: 1 })

has no generic type parameters provided so it will infer both:

  • B will be inferred as { a: number } based on the function argument;
  • and A will be inferred as unknown since it's not used anywhere in the function.

In the second case:

fn<Fixed>({ a: 1 })

you have specified one of the generic types and that unfortunately means that type inference will not be used for the rest of the type parameters – therefore:

  • A is specified as Fixed;
  • B is not given so instead of inferring it it will default to {}.

As annoying as this is, it is just how TypeScript works. Your second example with two function calls is the usual workaround to this issue.

Related issue on GitHub.