🤖 Pick PR #59232 (Fixed regression in reverse mapped ...) into release-5.5 (#59258)

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
This commit is contained in:
TypeScript Bot
2024-07-16 11:31:01 -07:00
committed by GitHub
parent 309a93cb21
commit 0d4ffed756
6 changed files with 300 additions and 13 deletions

View File

@@ -2193,6 +2193,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
/** Key is "/path/to/a.ts|/path/to/b.ts". */
var amalgamatedDuplicates: Map<string, DuplicateInfoForFiles> | undefined;
var reverseMappedCache = new Map<string, Type | undefined>();
var reverseHomomorphicMappedCache = new Map<string, Type | undefined>();
var ambientModulesCache: Symbol[] | undefined;
/**
* List of every ambient module with a "*" wildcard.
@@ -7003,12 +7004,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function shouldUsePlaceholderForProperty(propertySymbol: Symbol, context: NodeBuilderContext) {
// Use placeholders for reverse mapped types we've either already descended into, or which
// are nested reverse mappings within a mapping over a non-anonymous type. The later is a restriction mostly just to
// Use placeholders for reverse mapped types we've either
// (1) already descended into, or
// (2) are nested reverse mappings within a mapping over a non-anonymous type, or
// (3) are deeply nested properties that originate from the same mapped type.
// Condition (2) is a restriction mostly just to
// reduce the blowup in printback size from doing, eg, a deep reverse mapping over `Window`.
// Since anonymous types usually come from expressions, this allows us to preserve the output
// for deep mappings which likely come from expressions, while truncating those parts which
// come from mappings over library functions.
// Condition (3) limits printing of possibly infinitely deep reverse mapped types.
const depth = 3;
return !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped)
&& (
contains(context.reverseMappedStack, propertySymbol as ReverseMappedSymbol)
@@ -7016,7 +7022,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
context.reverseMappedStack?.[0]
&& !(getObjectFlags(last(context.reverseMappedStack).links.propertyType) & ObjectFlags.Anonymous)
)
|| isDeeplyNestedReverseMappedTypeProperty()
);
function isDeeplyNestedReverseMappedTypeProperty() {
if ((context.reverseMappedStack?.length ?? 0) < depth) {
return false;
}
for (let i = 0; i < depth; i++) {
const prop = context.reverseMappedStack![context.reverseMappedStack!.length - 1 - i];
if (prop.links.mappedType.symbol !== (propertySymbol as ReverseMappedSymbol).links.mappedType.symbol) {
return false;
}
}
return true;
}
}
function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) {
@@ -25604,11 +25623,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
*/
function inferTypeForHomomorphicMappedType(source: Type, target: MappedType, constraint: IndexType): Type | undefined {
const cacheKey = source.id + "," + target.id + "," + constraint.id;
if (reverseMappedCache.has(cacheKey)) {
return reverseMappedCache.get(cacheKey);
if (reverseHomomorphicMappedCache.has(cacheKey)) {
return reverseHomomorphicMappedCache.get(cacheKey);
}
const type = createReverseMappedType(source, target, constraint);
reverseMappedCache.set(cacheKey, type);
reverseHomomorphicMappedCache.set(cacheKey, type);
return type;
}