단 한줄로 요약하면 type paramater 의 타입을 유추하는것
// in chooseOverload
...
inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
...
candidate.typeParameters로 inferenceContext 를 만듬
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 호출 위의 코드를 호출 된다
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 를 호출해서 context 의 candidate 에 추가한다.TypeVariable 에 type candidate 를 추가한다.
가장 기본적인 흐름이다.