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 asunknown
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 asFixed
; -
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.