@@ -2322,6 +2322,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
23222322 var inferenceContexts: (InferenceContext | undefined)[] = [];
23232323 var inferenceContextCount = 0;
23242324
2325+ var activeTypeMappers: TypeMapper[] = [];
2326+ var activeTypeMappersCaches: Map<string, Type>[] = [];
2327+ var activeTypeMappersCount = 0;
2328+
23252329 var emptyStringType = getStringLiteralType("");
23262330 var zeroType = getNumberLiteralType(0);
23272331 var zeroBigIntType = getBigIntLiteralType({ negative: false, base10Value: "0" });
@@ -20858,10 +20862,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2085820862 error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
2085920863 return errorType;
2086020864 }
20865+ const index = findActiveMapper(mapper);
20866+ if (index === -1) {
20867+ pushActiveMapper(mapper);
20868+ }
20869+ const key = type.id + getAliasId(aliasSymbol, aliasTypeArguments);
20870+ const mapperCache = activeTypeMappersCaches[index !== -1 ? index : activeTypeMappersCount - 1];
20871+ const cached = mapperCache.get(key);
20872+ if (cached) {
20873+ return cached;
20874+ }
2086120875 totalInstantiationCount++;
2086220876 instantiationCount++;
2086320877 instantiationDepth++;
2086420878 const result = instantiateTypeWorker(type, mapper, aliasSymbol, aliasTypeArguments);
20879+ if (index === -1) {
20880+ popActiveMapper();
20881+ }
20882+ else {
20883+ mapperCache.set(key, result);
20884+ }
2086520885 instantiationDepth--;
2086620886 return result;
2086720887 }
@@ -27452,6 +27472,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2745227472 inference.inferredType = fallbackType && context.compareTypes(fallbackType, getTypeWithThisArgument(instantiatedConstraint, fallbackType)) ? fallbackType : instantiatedConstraint;
2745327473 }
2745427474 }
27475+ clearActiveMapperCaches();
2745527476 }
2745627477
2745727478 return inference.inferredType;
@@ -32668,6 +32689,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3266832689 }
3266932690 }
3267032691
32692+ function pushActiveMapper(mapper: TypeMapper) {
32693+ activeTypeMappers[activeTypeMappersCount] = mapper;
32694+ activeTypeMappersCaches[activeTypeMappersCount] = new Map();
32695+ activeTypeMappersCount++;
32696+ }
32697+
32698+ function popActiveMapper() {
32699+ activeTypeMappersCount--;
32700+ }
32701+
32702+ function findActiveMapper(mapper: TypeMapper) {
32703+ for (let i = activeTypeMappersCount - 1; i >= 0; i--) {
32704+ if (mapper === activeTypeMappers[i]) {
32705+ return i;
32706+ }
32707+ }
32708+ return -1;
32709+ }
32710+
32711+ function clearActiveMapperCaches() {
32712+ for (let i = activeTypeMappersCount - 1; i >= 0; i--) {
32713+ activeTypeMappersCaches[i].clear();
32714+ }
32715+ }
32716+
3267132717 function getContextualImportAttributeType(node: ImportAttribute) {
3267232718 return getTypeOfPropertyOfContextualType(getGlobalImportAttributesType(/*reportErrors*/ false), getNameFromImportAttribute(node));
3267332719 }
0 commit comments