inferTypeArguments 는 arg 의 타입에 따라서 inferTypes 를 호출

// inside inferArguments
inferTypes(context.inferences, getThisArgumentType(thisArgumentNode), thisType);

context 는 chooseOverload 에서 생성됨 chooseOverload 는 callexpression 을 검사할때 실행됨

// Inside chooseOverload
inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);

inferTypes 는 arg 의 타입과 선언된 타입과의 비교를 진행

inferTypes 는 target 이 typevariable 이 나올때까지 재귀적으로 호출

target 이 typevariable 이은 context 에 따른 candidate 를 추가

// inside inferTypes => inferFromTypes
if (target.flags & TypeFlags.TypeVariable) {
  const candidate = propagationType || source;
	...
	if(...){
	  inference.contraCandidates = append(inference.contraCandidates, candidate);
	}
	...
}

target 이 TypeVariable 이고 candidate 에 추가할수 있으면 context 에 candidate 를 추가

주의점

관련 이슈들

https://github.com/microsoft/TypeScript/issues/53018#issuecomment-1518558545