Merge pull request #13523 from Microsoft/fixNumericIndexedAccess

Fix numeric indexed access types
This commit is contained in:
Anders Hejlsberg 2017-01-17 11:51:52 -10:00 committed by GitHub
commit 4d501d1f44
5 changed files with 45 additions and 6 deletions

View file

@ -16091,14 +16091,24 @@ namespace ts {
}
function checkIndexedAccessIndexType(type: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode) {
if (type.flags & TypeFlags.IndexedAccess) {
// Check that the index type is assignable to 'keyof T' for the object type.
const objectType = (<IndexedAccessType>type).objectType;
const indexType = (<IndexedAccessType>type).indexType;
if (!isTypeAssignableTo(indexType, getIndexType(objectType))) {
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
if (!(type.flags & TypeFlags.IndexedAccess)) {
return type;
}
// Check if the index type is assignable to 'keyof T' for the object type.
const objectType = (<IndexedAccessType>type).objectType;
const indexType = (<IndexedAccessType>type).indexType;
if (isTypeAssignableTo(indexType, getIndexType(objectType))) {
return type;
}
// Check if we're indexing with a numeric type and the object type is a generic
// type with a constraint that has a numeric index signature.
if (maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && isTypeOfKind(indexType, TypeFlags.NumberLike)) {
const constraint = getBaseConstraintOfType(<TypeVariable | UnionOrIntersectionType>objectType);
if (constraint && getIndexInfoOfType(constraint, IndexKind.Number)) {
return type;
}
}
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
return type;
}

View file

@ -500,6 +500,10 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
var x = obj[key];
stringMap[x]; // Should be OK.
}
// Repro from #13514
declare function head<T extends Array<any>>(list: T): T[0];
//// [keyofAndIndexedAccess.js]
@ -1061,3 +1065,4 @@ declare function updateIds2<T extends {
}, K extends keyof T>(obj: T, key: K, stringMap: {
[oldId: string]: string;
}): void;
declare function head<T extends Array<any>>(list: T): T[0];

View file

@ -1806,3 +1806,13 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 498, 7))
}
// Repro from #13514
declare function head<T extends Array<any>>(list: T): T[0];
>head : Symbol(head, Decl(keyofAndIndexedAccess.ts, 500, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22))
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>list : Symbol(list, Decl(keyofAndIndexedAccess.ts, 504, 44))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22))

View file

@ -2128,3 +2128,13 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
>x : T[K]
}
// Repro from #13514
declare function head<T extends Array<any>>(list: T): T[0];
>head : <T extends any[]>(list: T) => T[0]
>T : T
>Array : T[]
>list : T
>T : T
>T : T

View file

@ -501,3 +501,7 @@ function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
var x = obj[key];
stringMap[x]; // Should be OK.
}
// Repro from #13514
declare function head<T extends Array<any>>(list: T): T[0];