- 
                Notifications
    
You must be signed in to change notification settings  - Fork 13.1k
 
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?