Home > Software design >  Why does infer choose the type from the last function from the intersection of functions?
Why does infer choose the type from the last function from the intersection of functions?

Time:01-05

type T = (() => 1) & (() => 2) extends () => infer R ? R : unknown
  1. Why is T not never (1 & 2)?
  2. Is the type always taken from the last function or from one of them?

CodePudding user response:

infer will always take the last overload when faced with an intersection (which is really just another way to describe overloads), no matter how you define it. The last overload is the last member in the intersection or last definition in the code:

type One = (() => 1) & (() => 2);
type Two = { (): 1; (): 2; };

type MutuallyAssignable = One extends Two ? Two extends One ? true : false : false;
//   ^? true

function three(): 1;
function three(): 2;
function three() { return 42 }

type Three = typeof three;

class C {
    four(): 1;
    four(): 2;
    four() { return 42 }
}

type Four = C["four"];

type T<F> = F extends (...args: any[]) => infer R ? R : unknown;

type T01 = T<One>;
//   ^? 2
type T02 = T<Two>;
//   ^? 2
type T03 = T<Three>;
//   ^? 2
type T04 = T<Four>;
//   ^? 2

Playground

  • Related