diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 912db011904..903c8cfda1c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6033,6 +6033,9 @@ namespace ts { function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) { if (maybeTypeOfKind(indexType, TypeFlags.TypeVariable | TypeFlags.Index) || isGenericMappedType(objectType)) { + if (objectType.flags & TypeFlags.Any) { + return objectType; + } // If the index type is generic or if the object type is a mapped type with a generic constraint, // we are performing a higher-order index access where we cannot meaningfully access the properties // of the object type. In those cases, we first check that the index type is assignable to 'keyof T' diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 1a0b90f3163..a9a5ee29993 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -353,6 +353,17 @@ interface Options2 { declare class Component2 { constructor(options: Options2); get(key: K): (Data & Computed)[K]; +} + +// Repro from #12641 + +interface R { + p: number; +} + +function f(p: K) { + let a: any; + a[p].add; // any } //// [keyofAndIndexedAccess.js] @@ -589,6 +600,10 @@ var c1 = new Component1({ } }); c1.get("hello"); +function f(p) { + var a; + a[p].add; // any +} //// [keyofAndIndexedAccess.d.ts] @@ -757,3 +772,7 @@ declare class Component2 { constructor(options: Options2); get(key: K): (Data & Computed)[K]; } +interface R { + p: number; +} +declare function f(p: K): void; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index bc9e53cdd7e..3d90b4ca276 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -1320,3 +1320,27 @@ declare class Component2 { >Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 351, 30)) >K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 353, 8)) } + +// Repro from #12641 + +interface R { +>R : Symbol(R, Decl(keyofAndIndexedAccess.ts, 354, 1)) + + p: number; +>p : Symbol(R.p, Decl(keyofAndIndexedAccess.ts, 358, 13)) +} + +function f(p: K) { +>f : Symbol(f, Decl(keyofAndIndexedAccess.ts, 360, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 362, 11)) +>R : Symbol(R, Decl(keyofAndIndexedAccess.ts, 354, 1)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 362, 30)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 362, 11)) + + let a: any; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 363, 7)) + + a[p].add; // any +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 363, 7)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 362, 30)) +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 7cd4b434af6..3b984643776 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -1560,3 +1560,30 @@ declare class Component2 { >Computed : Computed >K : K } + +// Repro from #12641 + +interface R { +>R : R + + p: number; +>p : number +} + +function f(p: K) { +>f : (p: K) => void +>K : K +>R : R +>p : K +>K : K + + let a: any; +>a : any + + a[p].add; // any +>a[p].add : any +>a[p] : any +>a : any +>p : K +>add : any +} diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index 3a2bb912c19..08bcfb28204 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -354,4 +354,15 @@ interface Options2 { declare class Component2 { constructor(options: Options2); get(key: K): (Data & Computed)[K]; +} + +// Repro from #12641 + +interface R { + p: number; +} + +function f(p: K) { + let a: any; + a[p].add; // any } \ No newline at end of file