Skip to content

Commit a660573

Browse files
committed
# This is a combination of 3 commits.
# This is the 1st commit message: # This is a combination of 2 commits. # This is the 1st commit message: # This is a combination of 3 commits. # This is the 1st commit message: init # This is the commit message #2: isIdentifier # This is the commit message #3: baselines # This is the commit message #2: rebase # This is the commit message #2: isIdentifier # This is the commit message #3: baselines
1 parent 5ef0439 commit a660573

11 files changed

+238
-13
lines changed

src/compiler/binder.ts

+1-1
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

+5
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

tests/baselines/reference/controlFlowOptionalChain.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -2057,11 +2057,11 @@ while (arr[i]?.tag === "left") {
20572057

20582058
if (arr[i]?.tag === "right") {
20592059
>arr[i]?.tag === "right" : boolean
2060-
>arr[i]?.tag : "left" | "right"
2060+
>arr[i]?.tag : "left"
20612061
>arr[i] : { tag: "left" | "right"; }
20622062
>arr : { tag: "left" | "right"; }[]
20632063
>i : number
2064-
>tag : "left" | "right"
2064+
>tag : "left"
20652065
>"right" : "right"
20662066

20672067
console.log("I should ALSO be reachable");

tests/baselines/reference/incrementOnNullAssertion.types

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,21 @@ if (foo[x] === undefined) {
2727
}
2828
else {
2929
let nu = foo[x]
30-
>nu : number | undefined
31-
>foo[x] : number | undefined
30+
>nu : number
31+
>foo[x] : number
3232
>foo : Dictionary<number>
3333
>x : "bar"
3434

3535
let n = foo[x]
36-
>n : number | undefined
37-
>foo[x] : number | undefined
36+
>n : number
37+
>foo[x] : number
3838
>foo : Dictionary<number>
3939
>x : "bar"
4040

4141
foo[x]!++
4242
>foo[x]!++ : number
4343
>foo[x]! : number
44-
>foo[x] : number | undefined
44+
>foo[x] : number
4545
>foo : Dictionary<number>
4646
>x : "bar"
4747
}
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+
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++;
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+
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+

tests/baselines/reference/noUncheckedIndexedAccess.errors.txt

+2-4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ tests/cases/conformance/pedantic/noUncheckedIndexedAccess.ts(90,7): error TS2322
3232
Type 'undefined' is not assignable to type 'string'.
3333
tests/cases/conformance/pedantic/noUncheckedIndexedAccess.ts(98,5): error TS2322: Type 'undefined' is not assignable to type '{ [key: string]: string; a: string; b: string; }[Key]'.
3434
Type 'undefined' is not assignable to type 'string'.
35-
tests/cases/conformance/pedantic/noUncheckedIndexedAccess.ts(99,11): error TS2322: Type 'string | undefined' is not assignable to type 'string'.
36-
Type 'undefined' is not assignable to type 'string'.
35+
tests/cases/conformance/pedantic/noUncheckedIndexedAccess.ts(99,11): error TS2322: Type 'undefined' is not assignable to type 'string'.
3736

3837

3938
==== tests/cases/conformance/pedantic/noUncheckedIndexedAccess.ts (31 errors) ====
@@ -201,8 +200,7 @@ tests/cases/conformance/pedantic/noUncheckedIndexedAccess.ts(99,11): error TS232
201200
!!! error TS2322: Type 'undefined' is not assignable to type 'string'.
202201
const v: string = myRecord2[key]; // Should error
203202
~
204-
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'.
205-
!!! error TS2322: Type 'undefined' is not assignable to type 'string'.
203+
!!! error TS2322: Type 'undefined' is not assignable to type 'string'.
206204
};
207205

208206

tests/baselines/reference/noUncheckedIndexedAccess.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ const fn3 = <Key extends keyof typeof myRecord2>(key: Key) => {
412412

413413
const v: string = myRecord2[key]; // Should error
414414
>v : string
415-
>myRecord2[key] : string | undefined
415+
>myRecord2[key] : undefined
416416
>myRecord2 : { [key: string]: string; a: string; b: string; }
417417
>key : Key
418418

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @strict: true
2+
3+
interface IEye {
4+
visibility: number | undefined
5+
}
6+
7+
interface IPirate {
8+
hands: number | undefined,
9+
eyes: IEye[]
10+
}
11+
12+
const pirates: IPirate[] = [];
13+
14+
const index: number = 1;
15+
16+
pirates[index].hands++;
17+
if (pirates[index].hands) pirates[index].hands++;
18+
19+
pirates[index].eyes[index].visibility++;
20+
if (pirates[index].eyes[index].visibility) pirates[index].eyes[index].visibility++;

0 commit comments

Comments
 (0)