Merge pull request #10009 from Microsoft/null-undefined-allowed-as-index-expressions

`Null` and `undefined` are allowed as index expressions
This commit is contained in:
Nathan Shively-Sanders 2016-08-16 15:46:42 -07:00 committed by GitHub
commit 01aaff7247
8 changed files with 199 additions and 2 deletions

View File

@ -10842,10 +10842,11 @@ namespace ts {
}
// Check for compatible indexer types.
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
const allowedNullableFlags = strictNullChecks ? 0 : TypeFlags.Nullable;
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol | allowedNullableFlags)) {
// Try to use a number indexer.
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike) || isForInVariableForNumericPropertyNames(node.argumentExpression)) {
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | allowedNullableFlags) || isForInVariableForNumericPropertyNames(node.argumentExpression)) {
const numberIndexInfo = getIndexInfoOfType(objectType, IndexKind.Number);
if (numberIndexInfo) {
getNodeLinks(node).resolvedIndexInfo = numberIndexInfo;

View File

@ -0,0 +1,22 @@
//// [indexWithUndefinedAndNull.ts]
interface N {
[n: number]: string;
}
interface S {
[s: string]: number;
}
let n: N;
let s: S;
let str: string = n[undefined];
str = n[null];
let num: number = s[undefined];
num = s[null];
//// [indexWithUndefinedAndNull.js]
var n;
var s;
var str = n[undefined];
str = n[null];
var num = s[undefined];
num = s[null];

View File

@ -0,0 +1,39 @@
=== tests/cases/compiler/indexWithUndefinedAndNull.ts ===
interface N {
>N : Symbol(N, Decl(indexWithUndefinedAndNull.ts, 0, 0))
[n: number]: string;
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 1, 5))
}
interface S {
>S : Symbol(S, Decl(indexWithUndefinedAndNull.ts, 2, 1))
[s: string]: number;
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 4, 5))
}
let n: N;
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 6, 3))
>N : Symbol(N, Decl(indexWithUndefinedAndNull.ts, 0, 0))
let s: S;
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 7, 3))
>S : Symbol(S, Decl(indexWithUndefinedAndNull.ts, 2, 1))
let str: string = n[undefined];
>str : Symbol(str, Decl(indexWithUndefinedAndNull.ts, 8, 3))
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 6, 3))
>undefined : Symbol(undefined)
str = n[null];
>str : Symbol(str, Decl(indexWithUndefinedAndNull.ts, 8, 3))
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 6, 3))
let num: number = s[undefined];
>num : Symbol(num, Decl(indexWithUndefinedAndNull.ts, 10, 3))
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 7, 3))
>undefined : Symbol(undefined)
num = s[null];
>num : Symbol(num, Decl(indexWithUndefinedAndNull.ts, 10, 3))
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 7, 3))

View File

@ -0,0 +1,47 @@
=== tests/cases/compiler/indexWithUndefinedAndNull.ts ===
interface N {
>N : N
[n: number]: string;
>n : number
}
interface S {
>S : S
[s: string]: number;
>s : string
}
let n: N;
>n : N
>N : N
let s: S;
>s : S
>S : S
let str: string = n[undefined];
>str : string
>n[undefined] : string
>n : N
>undefined : undefined
str = n[null];
>str = n[null] : string
>str : string
>n[null] : string
>n : N
>null : null
let num: number = s[undefined];
>num : number
>s[undefined] : number
>s : S
>undefined : undefined
num = s[null];
>num = s[null] : number
>num : number
>s[null] : number
>s : S
>null : null

View File

@ -0,0 +1,40 @@
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(9,19): error TS2454: Variable 'n' is used before being assigned.
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(9,19): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(10,7): error TS2454: Variable 'n' is used before being assigned.
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(10,7): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(11,19): error TS2454: Variable 's' is used before being assigned.
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(11,19): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(12,7): error TS2454: Variable 's' is used before being assigned.
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(12,7): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
==== tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts (8 errors) ====
interface N {
[n: number]: string;
}
interface S {
[s: string]: number;
}
let n: N;
let s: S;
let str: string = n[undefined];
~
!!! error TS2454: Variable 'n' is used before being assigned.
~~~~~~~~~~~~
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
str = n[null];
~
!!! error TS2454: Variable 'n' is used before being assigned.
~~~~~~~
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
let num: number = s[undefined];
~
!!! error TS2454: Variable 's' is used before being assigned.
~~~~~~~~~~~~
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
num = s[null];
~
!!! error TS2454: Variable 's' is used before being assigned.
~~~~~~~
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.

View File

@ -0,0 +1,22 @@
//// [indexWithUndefinedAndNullStrictNullChecks.ts]
interface N {
[n: number]: string;
}
interface S {
[s: string]: number;
}
let n: N;
let s: S;
let str: string = n[undefined];
str = n[null];
let num: number = s[undefined];
num = s[null];
//// [indexWithUndefinedAndNullStrictNullChecks.js]
var n;
var s;
var str = n[undefined];
str = n[null];
var num = s[undefined];
num = s[null];

View File

@ -0,0 +1,13 @@
// @strictNullChecks: false
interface N {
[n: number]: string;
}
interface S {
[s: string]: number;
}
let n: N;
let s: S;
let str: string = n[undefined];
str = n[null];
let num: number = s[undefined];
num = s[null];

View File

@ -0,0 +1,13 @@
// @strictNullChecks: true
interface N {
[n: number]: string;
}
interface S {
[s: string]: number;
}
let n: N;
let s: S;
let str: string = n[undefined];
str = n[null];
let num: number = s[undefined];
num = s[null];