From a7e8230cf138364a2f23c042b2349d6b5cc240ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 2 Dec 2025 20:07:40 +0100 Subject: [PATCH] Simplify `never` indexed by generic index types --- src/compiler/checker.ts | 2 +- .../reference/keyofAndIndexedAccess.errors.txt | 4 ++++ .../baselines/reference/keyofAndIndexedAccess.js | 7 +++++++ .../reference/keyofAndIndexedAccess.symbols | 15 +++++++++++++++ .../reference/keyofAndIndexedAccess.types | 12 ++++++++++++ .../types/keyof/keyofAndIndexedAccess.ts | 4 ++++ 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8e5c03560db3e..f089844a992b6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19611,7 +19611,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { isGenericTupleType(objectType) && !indexTypeLessThan(indexType, getTotalFixedElementCount(objectType.target)) : isGenericObjectType(objectType) && !(isTupleType(objectType) && indexTypeLessThan(indexType, getTotalFixedElementCount(objectType.target))) || isGenericReducibleType(objectType)) ) { - if (objectType.flags & TypeFlags.AnyOrUnknown) { + if (objectType.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) { return objectType; } // Defer the operation by creating an indexed access type. diff --git a/tests/baselines/reference/keyofAndIndexedAccess.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess.errors.txt index e833106df6fe5..05f425708bb02 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccess.errors.txt @@ -694,4 +694,8 @@ keyofAndIndexedAccess.ts(318,5): error TS2322: Type 'T[K]' is not assignable to const s: string = t[k]; t.cool; }; + + type IndexedNever = never[keyof T]; + type IndexedAny = any[keyof T]; + type IndexedUnknown = unknown[keyof T]; \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index ea10cf32f5e50..fd718fe3853e9 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -658,6 +658,10 @@ const cf2 = (t: T, const s: string = t[k]; t.cool; }; + +type IndexedNever = never[keyof T]; +type IndexedAny = any[keyof T]; +type IndexedUnknown = unknown[keyof T]; //// [keyofAndIndexedAccess.js] @@ -1435,3 +1439,6 @@ declare const cf1: (t: T, k: K) => void; declare const cf2: (t: T, k: K) => void; +type IndexedNever = never[keyof T]; +type IndexedAny = any[keyof T]; +type IndexedUnknown = unknown[keyof T]; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index 0d2b7218d5b0b..4520374edee31 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -2345,3 +2345,18 @@ const cf2 = (t: T, }; +type IndexedNever = never[keyof T]; +>IndexedNever : Symbol(IndexedNever, Decl(keyofAndIndexedAccess.ts, 656, 2)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 658, 18)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 658, 18)) + +type IndexedAny = any[keyof T]; +>IndexedAny : Symbol(IndexedAny, Decl(keyofAndIndexedAccess.ts, 658, 38)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 659, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 659, 16)) + +type IndexedUnknown = unknown[keyof T]; +>IndexedUnknown : Symbol(IndexedUnknown, Decl(keyofAndIndexedAccess.ts, 659, 34)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 660, 20)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 660, 20)) + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 6f0d4daec7e44..aa6256d0029fc 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -3450,3 +3450,15 @@ const cf2 = (t: T, }; +type IndexedNever = never[keyof T]; +>IndexedNever : never +> : ^^^^^ + +type IndexedAny = any[keyof T]; +>IndexedAny : any +> : ^^^ + +type IndexedUnknown = unknown[keyof T]; +>IndexedUnknown : unknown +> : ^^^^^^^ + diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index 56ff157a67fd0..166ed6f36fc5a 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -658,3 +658,7 @@ const cf2 = (t: T, const s: string = t[k]; t.cool; }; + +type IndexedNever = never[keyof T]; +type IndexedAny = any[keyof T]; +type IndexedUnknown = unknown[keyof T];