Always check index type validity for all types when an error node is present so we always issue an error (#26789)

* Always check index type validity for all types when an error node is present so we always issue an error

* Change type a bit
This commit is contained in:
Wesley Wigham 2018-09-04 16:00:28 -07:00 committed by GitHub
parent ca662419e8
commit 4ac8976750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 2 deletions

View File

@ -9380,13 +9380,24 @@ namespace ts {
const apparentObjectType = getApparentType(objectType);
if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Boolean)) {
const propTypes: Type[] = [];
let wasMissingProp = false;
for (const t of (<UnionType>indexType).types) {
const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false, missingType);
if (propType === missingType) {
return missingType;
if (!accessNode) {
// If there's no error node, we can immeditely stop, since error reporting is off
return missingType;
}
else {
// Otherwise we set a flag and return at the end of the loop so we still mark all errors
wasMissingProp = true;
}
}
propTypes.push(propType);
}
if (wasMissingProp) {
return missingType;
}
return getUnionType(propTypes);
}
return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true, missingType);

View File

@ -0,0 +1,9 @@
tests/cases/compiler/arrayIndexWithArrayFails.ts(3,16): error TS2538: Type 'string[]' cannot be used as an index type.
==== tests/cases/compiler/arrayIndexWithArrayFails.ts (1 errors) ====
declare const arr1: (string | string[])[];
declare const arr2: number[];
const j = arr2[arr1[0]]; // should error
~~~~~~~
!!! error TS2538: Type 'string[]' cannot be used as an index type.

View File

@ -0,0 +1,7 @@
//// [arrayIndexWithArrayFails.ts]
declare const arr1: (string | string[])[];
declare const arr2: number[];
const j = arr2[arr1[0]]; // should error
//// [arrayIndexWithArrayFails.js]
var j = arr2[arr1[0]]; // should error

View File

@ -0,0 +1,12 @@
=== tests/cases/compiler/arrayIndexWithArrayFails.ts ===
declare const arr1: (string | string[])[];
>arr1 : Symbol(arr1, Decl(arrayIndexWithArrayFails.ts, 0, 13))
declare const arr2: number[];
>arr2 : Symbol(arr2, Decl(arrayIndexWithArrayFails.ts, 1, 13))
const j = arr2[arr1[0]]; // should error
>j : Symbol(j, Decl(arrayIndexWithArrayFails.ts, 2, 5))
>arr2 : Symbol(arr2, Decl(arrayIndexWithArrayFails.ts, 1, 13))
>arr1 : Symbol(arr1, Decl(arrayIndexWithArrayFails.ts, 0, 13))

View File

@ -0,0 +1,15 @@
=== tests/cases/compiler/arrayIndexWithArrayFails.ts ===
declare const arr1: (string | string[])[];
>arr1 : (string | string[])[]
declare const arr2: number[];
>arr2 : number[]
const j = arr2[arr1[0]]; // should error
>j : any
>arr2[arr1[0]] : any
>arr2 : number[]
>arr1[0] : string | string[]
>arr1 : (string | string[])[]
>0 : 0

View File

@ -8,9 +8,12 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(25,18): error
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(26,18): error TS2538: Type 'void' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(27,18): error TS2538: Type 'undefined' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(28,18): error TS2538: Type '{ x: string; }' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'number'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(30,18): error TS2538: Type 'string & number' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'false' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'true' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(35,21): error TS2537: Type 'string[]' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(36,21): error TS2538: Type 'boolean' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(41,31): error TS2538: Type 'boolean' cannot be used as an index type.
@ -60,7 +63,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error
Type 'T' is not assignable to type 'U'.
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (33 errors) ====
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (36 errors) ====
class Shape {
name: string;
width: number;
@ -111,6 +114,8 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error
!!! error TS2538: Type '{ x: string; }' cannot be used as an index type.
type T20 = Shape[string | number]; // Error
~~~~~~~~~~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'number'.
~~~~~~~~~~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'string'.
type T21 = Shape[string & number]; // Error
~~~~~~~~~~~~~~~
@ -118,6 +123,10 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error
type T22 = Shape[string | boolean]; // Error
~~~~~~~~~~~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'string'.
~~~~~~~~~~~~~~~~
!!! error TS2538: Type 'false' cannot be used as an index type.
~~~~~~~~~~~~~~~~
!!! error TS2538: Type 'true' cannot be used as an index type.
type T30 = string[]["length"];
type T31 = string[][number];

View File

@ -0,0 +1,3 @@
declare const arr1: (string | string[])[];
declare const arr2: number[];
const j = arr2[arr1[0]]; // should error