Skip to content

Commit 9b1cbe0

Browse files
committed
Added type checks to avoid false positive results
1 parent d0547f1 commit 9b1cbe0

File tree

5 files changed

+97
-18
lines changed

5 files changed

+97
-18
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15589,8 +15589,8 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1558915589
return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type;
1559015590
}
1559115591
errorIfWritingToReadonlyIndex(indexInfo);
15592-
if (accessFlags & AccessFlags.IncludeUndefined && objectType.symbol.flags & (SymbolFlags.RegularEnum | SymbolFlags.ConstEnum)) {
15593-
if(indexType.flags & TypeFlags.EnumLiteral){
15592+
if (accessFlags & AccessFlags.IncludeUndefined && objectType.symbol && objectType.symbol.flags & (SymbolFlags.RegularEnum | SymbolFlags.ConstEnum)) {
15593+
if (indexType.symbol && indexType.flags & TypeFlags.EnumLiteral && getParentOfSymbol(indexType.symbol) === objectType.symbol) {
1559415594
return indexInfo.type;
1559515595
}
1559615596
}

tests/baselines/reference/noUncheckedIndexAccess.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,17 @@ enum Meat {
1515
//Avoiding a false positive
1616
const value = Meat[0]
1717

18-
const t = "testing"
19-
const value2 = Meat[t]
20-
18+
const valueUndefined = "testing"
19+
const value2 = Meat[valueUndefined]
20+
21+
enum A {
22+
a, b, c
23+
}
24+
enum B {
25+
x, y, z
26+
}
27+
28+
const value3 = A[B.x];
2129

2230
//// [noUncheckedIndexAccess.js]
2331
var Meat;
@@ -33,5 +41,18 @@ var union = Meat.Bacon;
3341
var valueUnion = Meat[union];
3442
//Avoiding a false positive
3543
var value = Meat[0];
36-
var t = "testing";
37-
var value2 = Meat[t];
44+
var valueUndefined = "testing";
45+
var value2 = Meat[valueUndefined];
46+
var A;
47+
(function (A) {
48+
A[A["a"] = 0] = "a";
49+
A[A["b"] = 1] = "b";
50+
A[A["c"] = 2] = "c";
51+
})(A || (A = {}));
52+
var B;
53+
(function (B) {
54+
B[B["x"] = 0] = "x";
55+
B[B["y"] = 1] = "y";
56+
B[B["z"] = 2] = "z";
57+
})(B || (B = {}));
58+
var value3 = A[B.x];

tests/baselines/reference/noUncheckedIndexAccess.symbols

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,35 @@ enum Meat {
5050
>value : Symbol(value, Decl(noUncheckedIndexAccess.ts, 14, 7))
5151
>Meat : Symbol(Meat, Decl(noUncheckedIndexAccess.ts, 0, 0))
5252

53-
const t = "testing"
54-
>t : Symbol(t, Decl(noUncheckedIndexAccess.ts, 16, 7))
53+
const valueUndefined = "testing"
54+
>valueUndefined : Symbol(valueUndefined, Decl(noUncheckedIndexAccess.ts, 16, 7))
5555

56-
const value2 = Meat[t]
56+
const value2 = Meat[valueUndefined]
5757
>value2 : Symbol(value2, Decl(noUncheckedIndexAccess.ts, 17, 7))
5858
>Meat : Symbol(Meat, Decl(noUncheckedIndexAccess.ts, 0, 0))
59-
>t : Symbol(t, Decl(noUncheckedIndexAccess.ts, 16, 7))
59+
>valueUndefined : Symbol(valueUndefined, Decl(noUncheckedIndexAccess.ts, 16, 7))
60+
61+
enum A {
62+
>A : Symbol(A, Decl(noUncheckedIndexAccess.ts, 17, 37))
63+
64+
a, b, c
65+
>a : Symbol(A.a, Decl(noUncheckedIndexAccess.ts, 19, 10))
66+
>b : Symbol(A.b, Decl(noUncheckedIndexAccess.ts, 20, 6))
67+
>c : Symbol(A.c, Decl(noUncheckedIndexAccess.ts, 20, 9))
68+
}
69+
enum B {
70+
>B : Symbol(B, Decl(noUncheckedIndexAccess.ts, 21, 3))
71+
72+
x, y, z
73+
>x : Symbol(B.x, Decl(noUncheckedIndexAccess.ts, 22, 10))
74+
>y : Symbol(B.y, Decl(noUncheckedIndexAccess.ts, 23, 6))
75+
>z : Symbol(B.z, Decl(noUncheckedIndexAccess.ts, 23, 9))
76+
}
77+
78+
const value3 = A[B.x];
79+
>value3 : Symbol(value3, Decl(noUncheckedIndexAccess.ts, 26, 7))
80+
>A : Symbol(A, Decl(noUncheckedIndexAccess.ts, 17, 37))
81+
>B.x : Symbol(B.x, Decl(noUncheckedIndexAccess.ts, 22, 10))
82+
>B : Symbol(B, Decl(noUncheckedIndexAccess.ts, 21, 3))
83+
>x : Symbol(B.x, Decl(noUncheckedIndexAccess.ts, 22, 10))
6084

tests/baselines/reference/noUncheckedIndexAccess.types

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,38 @@ enum Meat {
5353
>Meat : typeof Meat
5454
>0 : 0
5555

56-
const t = "testing"
57-
>t : "testing"
56+
const valueUndefined = "testing"
57+
>valueUndefined : "testing"
5858
>"testing" : "testing"
5959

60-
const value2 = Meat[t]
60+
const value2 = Meat[valueUndefined]
6161
>value2 : error
62-
>Meat[t] : error
62+
>Meat[valueUndefined] : error
6363
>Meat : typeof Meat
64-
>t : "testing"
64+
>valueUndefined : "testing"
65+
66+
enum A {
67+
>A : A
68+
69+
a, b, c
70+
>a : A.a
71+
>b : A.b
72+
>c : A.c
73+
}
74+
enum B {
75+
>B : B
76+
77+
x, y, z
78+
>x : B.x
79+
>y : B.y
80+
>z : B.z
81+
}
82+
83+
const value3 = A[B.x];
84+
>value3 : string | undefined
85+
>A[B.x] : string | undefined
86+
>A : typeof A
87+
>B.x : B.x
88+
>B : typeof B
89+
>x : B.x
6590

tests/cases/compiler/noUncheckedIndexAccess.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,14 @@ enum Meat {
1717
//Avoiding a false positive
1818
const value = Meat[0]
1919

20-
const t = "testing"
21-
const value2 = Meat[t]
20+
const valueUndefined = "testing"
21+
const value2 = Meat[valueUndefined]
22+
23+
enum A {
24+
a, b, c
25+
}
26+
enum B {
27+
x, y, z
28+
}
29+
30+
const value3 = A[B.x];

0 commit comments

Comments
 (0)