Skip to content

Commit 0d4ffed

Browse files
TypeScript BotAndarist
andauthored
🤖 Pick PR #59232 (Fixed regression in reverse mapped ...) into release-5.5 (#59258)
Co-authored-by: Mateusz BurzyÅ„ski <[email protected]>
1 parent 309a93c commit 0d4ffed

File tree

6 files changed

+300
-13
lines changed

6 files changed

+300
-13
lines changed

‎src/compiler/checker.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
21932193
/** Key is "/path/to/a.ts|/path/to/b.ts". */
21942194
var amalgamatedDuplicates: Map<string, DuplicateInfoForFiles> | undefined;
21952195
var reverseMappedCache = new Map<string, Type | undefined>();
2196+
var reverseHomomorphicMappedCache = new Map<string, Type | undefined>();
21962197
var ambientModulesCache: Symbol[] | undefined;
21972198
/**
21982199
* List of every ambient module with a "*" wildcard.
@@ -7003,20 +7004,38 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
70037004
}
70047005

70057006
function shouldUsePlaceholderForProperty(propertySymbol: Symbol, context: NodeBuilderContext) {
7006-
// Use placeholders for reverse mapped types we've either already descended into, or which
7007-
// are nested reverse mappings within a mapping over a non-anonymous type. The later is a restriction mostly just to
7007+
// Use placeholders for reverse mapped types we've either
7008+
// (1) already descended into, or
7009+
// (2) are nested reverse mappings within a mapping over a non-anonymous type, or
7010+
// (3) are deeply nested properties that originate from the same mapped type.
7011+
// Condition (2) is a restriction mostly just to
70087012
// reduce the blowup in printback size from doing, eg, a deep reverse mapping over `Window`.
70097013
// Since anonymous types usually come from expressions, this allows us to preserve the output
70107014
// for deep mappings which likely come from expressions, while truncating those parts which
70117015
// come from mappings over library functions.
7016+
// Condition (3) limits printing of possibly infinitely deep reverse mapped types.
7017+
const depth = 3;
70127018
return !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped)
70137019
&& (
70147020
contains(context.reverseMappedStack, propertySymbol as ReverseMappedSymbol)
70157021
|| (
70167022
context.reverseMappedStack?.[0]
70177023
&& !(getObjectFlags(last(context.reverseMappedStack).links.propertyType) & ObjectFlags.Anonymous)
70187024
)
7025+
|| isDeeplyNestedReverseMappedTypeProperty()
70197026
);
7027+
function isDeeplyNestedReverseMappedTypeProperty() {
7028+
if ((context.reverseMappedStack?.length ?? 0) < depth) {
7029+
return false;
7030+
}
7031+
for (let i = 0; i < depth; i++) {
7032+
const prop = context.reverseMappedStack![context.reverseMappedStack!.length - 1 - i];
7033+
if (prop.links.mappedType.symbol !== (propertySymbol as ReverseMappedSymbol).links.mappedType.symbol) {
7034+
return false;
7035+
}
7036+
}
7037+
return true;
7038+
}
70207039
}
70217040

70227041
function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) {
@@ -25604,11 +25623,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2560425623
*/
2560525624
function inferTypeForHomomorphicMappedType(source: Type, target: MappedType, constraint: IndexType): Type | undefined {
2560625625
const cacheKey = source.id + "," + target.id + "," + constraint.id;
25607-
if (reverseMappedCache.has(cacheKey)) {
25608-
return reverseMappedCache.get(cacheKey);
25626+
if (reverseHomomorphicMappedCache.has(cacheKey)) {
25627+
return reverseHomomorphicMappedCache.get(cacheKey);
2560925628
}
2561025629
const type = createReverseMappedType(source, target, constraint);
25611-
reverseMappedCache.set(cacheKey, type);
25630+
reverseHomomorphicMappedCache.set(cacheKey, type);
2561225631
return type;
2561325632
}
2561425633

0 commit comments

Comments
 (0)