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.