Skip to content

Commit 4d501d1

Browse files
authored
Merge pull request #13523 from Microsoft/fixNumericIndexedAccess
Fix numeric indexed access types
2 parents 899d512 + 59a8aa4 commit 4d501d1

File tree

5 files changed

+45
-6
lines changed

5 files changed

+45
-6
lines changed

src/compiler/checker.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16091,14 +16091,24 @@ namespace ts {
1609116091
}
1609216092

1609316093
function checkIndexedAccessIndexType(type: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode) {
16094-
if (type.flags & TypeFlags.IndexedAccess) {
16095-
// Check that the index type is assignable to 'keyof T' for the object type.
16096-
const objectType = (<IndexedAccessType>type).objectType;
16097-
const indexType = (<IndexedAccessType>type).indexType;
16098-
if (!isTypeAssignableTo(indexType, getIndexType(objectType))) {
16099-
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
16094+
if (!(type.flags & TypeFlags.IndexedAccess)) {
16095+
return type;
16096+
}
16097+
// Check if the index type is assignable to 'keyof T' for the object type.
16098+
const objectType = (<IndexedAccessType>type).objectType;
16099+
const indexType = (<IndexedAccessType>type).indexType;
16100+
if (isTypeAssignableTo(indexType, getIndexType(objectType))) {
16101+
return type;
16102+
}
16103+
// Check if we're indexing with a numeric type and the object type is a generic
16104+
// type with a constraint that has a numeric index signature.
16105+
if (maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && isTypeOfKind(indexType, TypeFlags.NumberLike)) {
16106+
const constraint = getBaseConstraintOfType(<TypeVariable | UnionOrIntersectionType>objectType);
16107+
if (constraint && getIndexInfoOfType(constraint, IndexKind.Number)) {
16108+
return type;
1610016109
}
1610116110
}
16111+
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
1610216112
return type;
1610316113
}
1610416114

tests/baselines/reference/keyofAndIndexedAccess.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
500500
var x = obj[key];
501501
stringMap[x]; // Should be OK.
502502
}
503+
504+
// Repro from #13514
505+
506+
declare function head<T extends Array<any>>(list: T): T[0];
503507

504508

505509
//// [keyofAndIndexedAccess.js]
@@ -1061,3 +1065,4 @@ declare function updateIds2<T extends {
10611065
}, K extends keyof T>(obj: T, key: K, stringMap: {
10621066
[oldId: string]: string;
10631067
}): void;
1068+
declare function head<T extends Array<any>>(list: T): T[0];

tests/baselines/reference/keyofAndIndexedAccess.symbols

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,3 +1806,13 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
18061806
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 498, 7))
18071807
}
18081808

1809+
// Repro from #13514
1810+
1811+
declare function head<T extends Array<any>>(list: T): T[0];
1812+
>head : Symbol(head, Decl(keyofAndIndexedAccess.ts, 500, 1))
1813+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22))
1814+
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
1815+
>list : Symbol(list, Decl(keyofAndIndexedAccess.ts, 504, 44))
1816+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22))
1817+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22))
1818+

tests/baselines/reference/keyofAndIndexedAccess.types

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,3 +2128,13 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
21282128
>x : T[K]
21292129
}
21302130

2131+
// Repro from #13514
2132+
2133+
declare function head<T extends Array<any>>(list: T): T[0];
2134+
>head : <T extends any[]>(list: T) => T[0]
2135+
>T : T
2136+
>Array : T[]
2137+
>list : T
2138+
>T : T
2139+
>T : T
2140+

tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,3 +501,7 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
501501
var x = obj[key];
502502
stringMap[x]; // Should be OK.
503503
}
504+
505+
// Repro from #13514
506+
507+
declare function head<T extends Array<any>>(list: T): T[0];

0 commit comments

Comments
 (0)