From 80eb1f99b443134c0bf67c565c09652c8c01e710 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 May 2024 08:06:32 -0700 Subject: [PATCH 1/3] Properly account for thisArgument in intersection apparent type caching --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 86acdb7c44b6d..e3cc0a951c8ea 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14565,7 +14565,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getApparentTypeOfIntersectionType(type: IntersectionType, thisArgument: Type) { - return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, thisArgument, /*needApparentType*/ true)); + const key = `I${getTypeId(type)},${getTypeId(thisArgument)}`; + return getCachedType(key) ?? setCachedType(key, getTypeWithThisArgument(type, thisArgument, /*needApparentType*/ true)); } function getResolvedTypeParameterDefault(typeParameter: TypeParameter): Type | undefined { From 80186726744c820cb32923fb4808de17ae983b6d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 May 2024 10:58:15 -0700 Subject: [PATCH 2/3] Only use global cache when type and thisArgument differ --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e3cc0a951c8ea..eb3a403d9272c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14565,6 +14565,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getApparentTypeOfIntersectionType(type: IntersectionType, thisArgument: Type) { + if (type === thisArgument) { + return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, thisArgument, /*needApparentType*/ true)); + } const key = `I${getTypeId(type)},${getTypeId(thisArgument)}`; return getCachedType(key) ?? setCachedType(key, getTypeWithThisArgument(type, thisArgument, /*needApparentType*/ true)); } From dc620f2bf2f21d82fd0b376b12ef3fd10ccf33de Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 May 2024 11:20:40 -0700 Subject: [PATCH 3/3] Add regression test --- .../intersectionApparentTypeCaching.symbols | 19 +++++++++++++++++++ .../intersectionApparentTypeCaching.types | 17 +++++++++++++++++ .../intersectionApparentTypeCaching.ts | 8 ++++++++ 3 files changed, 44 insertions(+) create mode 100644 tests/baselines/reference/intersectionApparentTypeCaching.symbols create mode 100644 tests/baselines/reference/intersectionApparentTypeCaching.types create mode 100644 tests/cases/compiler/intersectionApparentTypeCaching.ts diff --git a/tests/baselines/reference/intersectionApparentTypeCaching.symbols b/tests/baselines/reference/intersectionApparentTypeCaching.symbols new file mode 100644 index 0000000000000..53c9c28862685 --- /dev/null +++ b/tests/baselines/reference/intersectionApparentTypeCaching.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/intersectionApparentTypeCaching.ts] //// + +=== intersectionApparentTypeCaching.ts === +// https://github.com/microsoft/TypeScript/issues/58175 + +type TX = T["length"]; +>TX : Symbol(TX, Decl(intersectionApparentTypeCaching.ts, 0, 0)) +>T : Symbol(T, Decl(intersectionApparentTypeCaching.ts, 2, 8)) +>T : Symbol(T, Decl(intersectionApparentTypeCaching.ts, 2, 8)) + +type T0 = U; +>T0 : Symbol(T0, Decl(intersectionApparentTypeCaching.ts, 2, 48)) +>U : Symbol(U, Decl(intersectionApparentTypeCaching.ts, 3, 8)) +>U : Symbol(U, Decl(intersectionApparentTypeCaching.ts, 3, 8)) + +type T1 = T0; +>T1 : Symbol(T1, Decl(intersectionApparentTypeCaching.ts, 3, 38)) +>T0 : Symbol(T0, Decl(intersectionApparentTypeCaching.ts, 2, 48)) + diff --git a/tests/baselines/reference/intersectionApparentTypeCaching.types b/tests/baselines/reference/intersectionApparentTypeCaching.types new file mode 100644 index 0000000000000..a8a3b40084689 --- /dev/null +++ b/tests/baselines/reference/intersectionApparentTypeCaching.types @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/intersectionApparentTypeCaching.ts] //// + +=== intersectionApparentTypeCaching.ts === +// https://github.com/microsoft/TypeScript/issues/58175 + +type TX = T["length"]; +>TX : TX +> : ^^^^^ + +type T0 = U; +>T0 : U +> : ^ + +type T1 = T0; +>T1 : string[] +> : ^^^^^^^^ + diff --git a/tests/cases/compiler/intersectionApparentTypeCaching.ts b/tests/cases/compiler/intersectionApparentTypeCaching.ts new file mode 100644 index 0000000000000..1325c4d6f2d7c --- /dev/null +++ b/tests/cases/compiler/intersectionApparentTypeCaching.ts @@ -0,0 +1,8 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/58175 + +type TX = T["length"]; +type T0 = U; +type T1 = T0;