단 한줄로 요약하면 type paramater 의 타입을 유추하는것

context

// in chooseOverload 
...
inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
...

candidate.typeParameters로 inferenceContext 를 만듬

inferTypeArguments

function inferTypeArguments(node: CallLikeExpression, ..., context: InferenceContext): Type[] {
// in inferTypeArguments
for (let i = 0; i < argCount; i++) {
  const arg = args[i];
  if (arg.kind !== SyntaxKind.OmittedExpression) {
    const paramType = getTypeAtPosition(signature, i);
    if (couldContainTypeVariables(paramType)) {
      const argType = checkExpressionWithContextualType(
        arg,
        paramType,
        context,
        checkMode
      );
      inferTypes(context.inferences, argType, paramType);
    }
  }
}

inferTypes 호출 위의 코드를 호출 된다

inferTypes

function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type){
	...
	function inferFromTypes(source: Type, target: Type): void {
		...
		if (target.flags & TypeFlags.Union) 
		...
		if (target.flags & TypeFlags.TypeVariable){
			...
			inference.contraCandidates = append(inference.contraCandidates, candidate);
		}
	}
}

inferTypes는 source 와 target 의 타입들을 분해해서 inferFromTypes를 재귀적으로 호출한다.

만약 object type 일경우 inferFromObjectTypes ⇒ inferFromProperties, inferFromSignatures, inferFromIndexTypes inferFromProperties 에서는 inferFromTypes 에 source, target 의 Property 들을 inferFromTypes 넣어서 호출한다.

최종적으로는 targe type 이 TypeVariable이 될떄까지 분해하고 append 를 호출해서 contextcandidate 에 추가한다.TypeVariabletype candidate 를 추가한다.

가장 기본적인 흐름이다.