Description
TypeScript Version: 3.3.0-dev.20181205
Search Terms:
conditional type, infer, overload, no-arg, zero arguments, strictFunctionTypes
Note that this issue is not about the behavior where the last overload is examined in conditional type inference of a single signature, where some might expect a union or an argument-based choice.
Code
// turn on --strictFunctionTypes
type InferTwoOverloads<F extends Function> =
F extends { (...a1: infer A1): infer R1, (...a0: infer A0): infer R0 } ?
[(...a1: A1) => R1, (...a0: A0) => R0] :
never;
type Expected = InferTwoOverloads<((x: string) => number) & (() => string)>
// [(x: string) => number, () => string]
type JustOneSignature = InferTwoOverloads<((x: string) => number)>;
// never
type JustTheOtherSignature = InferTwoOverloads<(() => string)>;
// [(...a1: unknown[]) => {}, () => string]
Expected behavior:
I would expect that either both JustOneSignature
and JustTheOtherSignature
would be never
, or both JustOneSignature
and JustTheOtherSignature
would evaluate to a two-tuple where the first signature is... something. I suppose (...a1: unknown[])=>{}
? Or maybe it should be a copy of one of the other overloads? Or something in between?
Actual behavior:
It looks a zero-argument function is being treated pathologically during conditional type inference; if a type is callable with zero arguments, it will be considered assignable to any number of overloads with what looks like failed inference for the types of the arguments (unknown[]
) and the return ({}
). Otherwise, if a type is only callable with at least one argument, it will only be considered assignable to the matching number of overloads.
This distinction only seems to happen with --strictFunctionTypes
on. If you turn it off, JustOneSignature
above becomes [(...a1: unknown[]) => {}, (x: string) => number]
, which is at least consistent with the zero-argument situation.
Playground Link:
🔗
Related Issues:
- Not the same issue as Function argument inference only handles one overload #26591 or Return type inference of overloaded function when argument is known #27027, or the choose-last-overload behavior described in Type inference in conditional types #21496
- Maybe related to unknown[] as rest params with generic parameter breaks generic inference #27439?
- Or maybe Adding infer in a conditional type changes the resulting branch #22615?