diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 18f0846b713..cb2ce91dd86 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9108,6 +9108,11 @@ namespace ts { return type; } + function maybeTypeParameterReference(node: Node) { + return !(node.kind === SyntaxKind.QualifiedName || + node.parent.kind === SyntaxKind.TypeReference && (node.parent).typeArguments && node === (node.parent).typeName); + } + function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks // between the node and the type parameter declaration, if the node contains actual references to the @@ -9124,7 +9129,8 @@ namespace ts { case SyntaxKind.ThisType: return tp.isThisType; case SyntaxKind.Identifier: - return !tp.isThisType && isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp; + return !tp.isThisType && isPartOfTypeNode(node) && maybeTypeParameterReference(node) && + getTypeFromTypeNode(node) === tp; case SyntaxKind.TypeQuery: return true; } diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index 0e7844babc6..c0c4211174c 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -191,4 +191,15 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2 type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; + + // Repro from #23100 + + type A2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; + + type B2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; + + type C2 = + T extends object ? { [Q in keyof T]: C2; } : T; \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes2.js b/tests/baselines/reference/conditionalTypes2.js index 7afb39d42bb..1f95e7eb8d9 100644 --- a/tests/baselines/reference/conditionalTypes2.js +++ b/tests/baselines/reference/conditionalTypes2.js @@ -134,6 +134,17 @@ type B = type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; + +// Repro from #23100 + +type A2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; + +type B2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; + +type C2 = + T extends object ? { [Q in keyof T]: C2; } : T; //// [conditionalTypes2.js] @@ -284,3 +295,12 @@ declare type C = { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; +declare type A2 = T extends object ? T extends any[] ? T : { + [Q in keyof T]: A2; +} : T; +declare type B2 = T extends object ? T extends any[] ? T : { + [Q in keyof T]: B2; +} : T; +declare type C2 = T extends object ? { + [Q in keyof T]: C2; +} : T; diff --git a/tests/baselines/reference/conditionalTypes2.symbols b/tests/baselines/reference/conditionalTypes2.symbols index 00509458253..fb03b868a1d 100644 --- a/tests/baselines/reference/conditionalTypes2.symbols +++ b/tests/baselines/reference/conditionalTypes2.symbols @@ -496,3 +496,58 @@ type C = >V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9)) >E : Symbol(E, Decl(conditionalTypes2.ts, 133, 12)) +// Repro from #23100 + +type A2 = +>A2 : Symbol(A2, Decl(conditionalTypes2.ts, 134, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 138, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 138, 13)) + + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 139, 48)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>A2 : Symbol(A2, Decl(conditionalTypes2.ts, 134, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 139, 48)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 138, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 138, 13)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) + +type B2 = +>B2 : Symbol(B2, Decl(conditionalTypes2.ts, 139, 85)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 141, 10)) + + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 142, 48)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>B2 : Symbol(B2, Decl(conditionalTypes2.ts, 139, 85)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 142, 48)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 141, 10)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) + +type C2 = +>C2 : Symbol(C2, Decl(conditionalTypes2.ts, 142, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 144, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 144, 13)) + + T extends object ? { [Q in keyof T]: C2; } : T; +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 145, 26)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>C2 : Symbol(C2, Decl(conditionalTypes2.ts, 142, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 145, 26)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 144, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 144, 13)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) + diff --git a/tests/baselines/reference/conditionalTypes2.types b/tests/baselines/reference/conditionalTypes2.types index 5af4de235c8..906bc7e27df 100644 --- a/tests/baselines/reference/conditionalTypes2.types +++ b/tests/baselines/reference/conditionalTypes2.types @@ -526,3 +526,58 @@ type C = >V : V >E : E +// Repro from #23100 + +type A2 = +>A2 : A2 +>T : T +>V : V +>E : E + + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; +>T : T +>T : T +>T : T +>Q : Q +>T : T +>A2 : A2 +>T : T +>Q : Q +>V : V +>E : E +>T : T + +type B2 = +>B2 : B2 +>T : T +>V : V + + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; +>T : T +>T : T +>T : T +>Q : Q +>T : T +>B2 : B2 +>T : T +>Q : Q +>V : V +>T : T + +type C2 = +>C2 : C2 +>T : T +>V : V +>E : E + + T extends object ? { [Q in keyof T]: C2; } : T; +>T : T +>Q : Q +>T : T +>C2 : C2 +>T : T +>Q : Q +>V : V +>E : E +>T : T + diff --git a/tests/cases/conformance/types/conditional/conditionalTypes2.ts b/tests/cases/conformance/types/conditional/conditionalTypes2.ts index 4002ab6a0a7..be758945469 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes2.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes2.ts @@ -136,3 +136,14 @@ type B = type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; + +// Repro from #23100 + +type A2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; + +type B2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; + +type C2 = + T extends object ? { [Q in keyof T]: C2; } : T;