Skip to content

Commit dbbc3ae

Browse files
committed
isIdentifier
1 parent 948763a commit dbbc3ae

7 files changed

+217
-4
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ namespace ts {
889889
return isDottedName(expr)
890890
|| (isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression)
891891
|| isBinaryExpression(expr) && expr.operatorToken.kind === SyntaxKind.CommaToken && isNarrowableReference(expr.right)
892-
|| isElementAccessExpression(expr) && isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression)
892+
|| isElementAccessExpression(expr) && ((isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression)) || isIdentifier(expr.argumentExpression))
893893
|| isAssignmentExpression(expr) && isNarrowableReference(expr.left);
894894
}
895895

src/compiler/checker.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32621,6 +32621,11 @@ namespace ts {
3262132621
case SyntaxKind.ExclamationEqualsToken:
3262232622
case SyntaxKind.EqualsEqualsEqualsToken:
3262332623
case SyntaxKind.ExclamationEqualsEqualsToken:
32624+
if (isPropertyAccessExpression(left) &&
32625+
isElementAccessExpression(left.expression) &&
32626+
isIdentifier(left.expression.expression)) {
32627+
return booleanType;
32628+
}
3262432629
reportOperatorErrorUnless((left, right) => isTypeEqualityComparableTo(left, right) || isTypeEqualityComparableTo(right, left));
3262532630
return booleanType;
3262632631

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
tests/cases/compiler/narrowingByNonLiteralIndexedAccess.ts(14,1): error TS2532: Object is possibly 'undefined'.
2+
tests/cases/compiler/narrowingByNonLiteralIndexedAccess.ts(17,1): error TS2532: Object is possibly 'undefined'.
3+
4+
5+
==== tests/cases/compiler/narrowingByNonLiteralIndexedAccess.ts (2 errors) ====
6+
interface IEye {
7+
visibility: number | undefined
8+
}
9+
10+
interface IPirate {
11+
hands: number | undefined,
12+
eyes: IEye[]
13+
}
14+
15+
const pirates: IPirate[] = [];
16+
17+
const index: number = 1;
18+
19+
pirates[index].hands++;
20+
~~~~~~~~~~~~~~~~~~~~
21+
!!! error TS2532: Object is possibly 'undefined'.
22+
if (pirates[index].hands) pirates[index].hands++;
23+
24+
pirates[index].eyes[index].visibility++;
25+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26+
!!! error TS2532: Object is possibly 'undefined'.
27+
if (pirates[index].eyes[index].visibility) pirates[index].eyes[index].visibility++;
28+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//// [narrowingByNonLiteralIndexedAccess.ts]
2+
interface IEye {
3+
visibility: number | undefined
4+
}
5+
6+
interface IPirate {
7+
hands: number | undefined,
8+
eyes: IEye[]
9+
}
10+
11+
const pirates: IPirate[] = [];
12+
13+
const index: number = 1;
14+
15+
pirates[index].hands++;
16+
if (pirates[index].hands) pirates[index].hands++;
17+
18+
pirates[index].eyes[index].visibility++;
19+
if (pirates[index].eyes[index].visibility) pirates[index].eyes[index].visibility++;
20+
21+
22+
//// [narrowingByNonLiteralIndexedAccess.js]
23+
"use strict";
24+
var pirates = [];
25+
var index = 1;
26+
pirates[index].hands++;
27+
if (pirates[index].hands)
28+
pirates[index].hands++;
29+
pirates[index].eyes[index].visibility++;
30+
if (pirates[index].eyes[index].visibility)
31+
pirates[index].eyes[index].visibility++;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
=== tests/cases/compiler/narrowingByNonLiteralIndexedAccess.ts ===
2+
interface IEye {
3+
>IEye : Symbol(IEye, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 0))
4+
5+
visibility: number | undefined
6+
>visibility : Symbol(IEye.visibility, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 16))
7+
}
8+
9+
interface IPirate {
10+
>IPirate : Symbol(IPirate, Decl(narrowingByNonLiteralIndexedAccess.ts, 2, 1))
11+
12+
hands: number | undefined,
13+
>hands : Symbol(IPirate.hands, Decl(narrowingByNonLiteralIndexedAccess.ts, 4, 19))
14+
15+
eyes: IEye[]
16+
>eyes : Symbol(IPirate.eyes, Decl(narrowingByNonLiteralIndexedAccess.ts, 5, 30))
17+
>IEye : Symbol(IEye, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 0))
18+
}
19+
20+
const pirates: IPirate[] = [];
21+
>pirates : Symbol(pirates, Decl(narrowingByNonLiteralIndexedAccess.ts, 9, 5))
22+
>IPirate : Symbol(IPirate, Decl(narrowingByNonLiteralIndexedAccess.ts, 2, 1))
23+
24+
const index: number = 1;
25+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
26+
27+
pirates[index].hands++;
28+
>pirates[index].hands : Symbol(IPirate.hands, Decl(narrowingByNonLiteralIndexedAccess.ts, 4, 19))
29+
>pirates : Symbol(pirates, Decl(narrowingByNonLiteralIndexedAccess.ts, 9, 5))
30+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
31+
>hands : Symbol(IPirate.hands, Decl(narrowingByNonLiteralIndexedAccess.ts, 4, 19))
32+
33+
if (pirates[index].hands) pirates[index].hands++;
34+
>pirates[index].hands : Symbol(IPirate.hands, Decl(narrowingByNonLiteralIndexedAccess.ts, 4, 19))
35+
>pirates : Symbol(pirates, Decl(narrowingByNonLiteralIndexedAccess.ts, 9, 5))
36+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
37+
>hands : Symbol(IPirate.hands, Decl(narrowingByNonLiteralIndexedAccess.ts, 4, 19))
38+
>pirates[index].hands : Symbol(IPirate.hands, Decl(narrowingByNonLiteralIndexedAccess.ts, 4, 19))
39+
>pirates : Symbol(pirates, Decl(narrowingByNonLiteralIndexedAccess.ts, 9, 5))
40+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
41+
>hands : Symbol(IPirate.hands, Decl(narrowingByNonLiteralIndexedAccess.ts, 4, 19))
42+
43+
pirates[index].eyes[index].visibility++;
44+
>pirates[index].eyes[index].visibility : Symbol(IEye.visibility, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 16))
45+
>pirates[index].eyes : Symbol(IPirate.eyes, Decl(narrowingByNonLiteralIndexedAccess.ts, 5, 30))
46+
>pirates : Symbol(pirates, Decl(narrowingByNonLiteralIndexedAccess.ts, 9, 5))
47+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
48+
>eyes : Symbol(IPirate.eyes, Decl(narrowingByNonLiteralIndexedAccess.ts, 5, 30))
49+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
50+
>visibility : Symbol(IEye.visibility, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 16))
51+
52+
if (pirates[index].eyes[index].visibility) pirates[index].eyes[index].visibility++;
53+
>pirates[index].eyes[index].visibility : Symbol(IEye.visibility, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 16))
54+
>pirates[index].eyes : Symbol(IPirate.eyes, Decl(narrowingByNonLiteralIndexedAccess.ts, 5, 30))
55+
>pirates : Symbol(pirates, Decl(narrowingByNonLiteralIndexedAccess.ts, 9, 5))
56+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
57+
>eyes : Symbol(IPirate.eyes, Decl(narrowingByNonLiteralIndexedAccess.ts, 5, 30))
58+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
59+
>visibility : Symbol(IEye.visibility, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 16))
60+
>pirates[index].eyes[index].visibility : Symbol(IEye.visibility, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 16))
61+
>pirates[index].eyes : Symbol(IPirate.eyes, Decl(narrowingByNonLiteralIndexedAccess.ts, 5, 30))
62+
>pirates : Symbol(pirates, Decl(narrowingByNonLiteralIndexedAccess.ts, 9, 5))
63+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
64+
>eyes : Symbol(IPirate.eyes, Decl(narrowingByNonLiteralIndexedAccess.ts, 5, 30))
65+
>index : Symbol(index, Decl(narrowingByNonLiteralIndexedAccess.ts, 11, 5))
66+
>visibility : Symbol(IEye.visibility, Decl(narrowingByNonLiteralIndexedAccess.ts, 0, 16))
67+
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
=== tests/cases/compiler/narrowingByNonLiteralIndexedAccess.ts ===
2+
interface IEye {
3+
visibility: number | undefined
4+
>visibility : number | undefined
5+
}
6+
7+
interface IPirate {
8+
hands: number | undefined,
9+
>hands : number | undefined
10+
11+
eyes: IEye[]
12+
>eyes : IEye[]
13+
}
14+
15+
const pirates: IPirate[] = [];
16+
>pirates : IPirate[]
17+
>[] : never[]
18+
19+
const index: number = 1;
20+
>index : number
21+
>1 : 1
22+
23+
pirates[index].hands++;
24+
>pirates[index].hands++ : number
25+
>pirates[index].hands : number | undefined
26+
>pirates[index] : IPirate
27+
>pirates : IPirate[]
28+
>index : number
29+
>hands : number | undefined
30+
31+
if (pirates[index].hands) pirates[index].hands++;
32+
>pirates[index].hands : number | undefined
33+
>pirates[index] : IPirate
34+
>pirates : IPirate[]
35+
>index : number
36+
>hands : number | undefined
37+
>pirates[index].hands++ : number
38+
>pirates[index].hands : number
39+
>pirates[index] : IPirate
40+
>pirates : IPirate[]
41+
>index : number
42+
>hands : number
43+
44+
pirates[index].eyes[index].visibility++;
45+
>pirates[index].eyes[index].visibility++ : number
46+
>pirates[index].eyes[index].visibility : number | undefined
47+
>pirates[index].eyes[index] : IEye
48+
>pirates[index].eyes : IEye[]
49+
>pirates[index] : IPirate
50+
>pirates : IPirate[]
51+
>index : number
52+
>eyes : IEye[]
53+
>index : number
54+
>visibility : number | undefined
55+
56+
if (pirates[index].eyes[index].visibility) pirates[index].eyes[index].visibility++;
57+
>pirates[index].eyes[index].visibility : number | undefined
58+
>pirates[index].eyes[index] : IEye
59+
>pirates[index].eyes : IEye[]
60+
>pirates[index] : IPirate
61+
>pirates : IPirate[]
62+
>index : number
63+
>eyes : IEye[]
64+
>index : number
65+
>visibility : number | undefined
66+
>pirates[index].eyes[index].visibility++ : number
67+
>pirates[index].eyes[index].visibility : number
68+
>pirates[index].eyes[index] : IEye
69+
>pirates[index].eyes : IEye[]
70+
>pirates[index] : IPirate
71+
>pirates : IPirate[]
72+
>index : number
73+
>eyes : IEye[]
74+
>index : number
75+
>visibility : number
76+
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
// @strict: true
22

3+
interface IEye {
4+
visibility: number | undefined
5+
}
6+
37
interface IPirate {
4-
hands: number | undefined
8+
hands: number | undefined,
9+
eyes: IEye[]
510
}
611

712
const pirates: IPirate[] = [];
813

914
const index: number = 1;
1015

11-
pirates[index].hands;
1216
pirates[index].hands++;
17+
if (pirates[index].hands) pirates[index].hands++;
1318

14-
if (pirates[index].hands) pirates[index].hands++;
19+
pirates[index].eyes[index].visibility++;
20+
if (pirates[index].eyes[index].visibility) pirates[index].eyes[index].visibility++;

0 commit comments

Comments
 (0)