diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c89299ce6b1..679e79ded0c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15589,8 +15589,8 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n") return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; } errorIfWritingToReadonlyIndex(indexInfo); - if (accessFlags & AccessFlags.IncludeUndefined && objectType.symbol.flags & (SymbolFlags.RegularEnum | SymbolFlags.ConstEnum)) { - if(indexType.flags & TypeFlags.EnumLiteral){ + if (accessFlags & AccessFlags.IncludeUndefined && objectType.symbol && objectType.symbol.flags & (SymbolFlags.RegularEnum | SymbolFlags.ConstEnum)) { + if (indexType.symbol && indexType.flags & TypeFlags.EnumLiteral && getParentOfSymbol(indexType.symbol) === objectType.symbol) { return indexInfo.type; } } diff --git a/tests/baselines/reference/noUncheckedIndexAccess.js b/tests/baselines/reference/noUncheckedIndexAccess.js index 3b1e3839e1c..cde4a72ff6d 100644 --- a/tests/baselines/reference/noUncheckedIndexAccess.js +++ b/tests/baselines/reference/noUncheckedIndexAccess.js @@ -15,9 +15,17 @@ enum Meat { //Avoiding a false positive const value = Meat[0] - const t = "testing" - const value2 = Meat[t] - + const valueUndefined = "testing" + const value2 = Meat[valueUndefined] + + enum A { + a, b, c + } + enum B { + x, y, z + } + + const value3 = A[B.x]; //// [noUncheckedIndexAccess.js] var Meat; @@ -33,5 +41,18 @@ var union = Meat.Bacon; var valueUnion = Meat[union]; //Avoiding a false positive var value = Meat[0]; -var t = "testing"; -var value2 = Meat[t]; +var valueUndefined = "testing"; +var value2 = Meat[valueUndefined]; +var A; +(function (A) { + A[A["a"] = 0] = "a"; + A[A["b"] = 1] = "b"; + A[A["c"] = 2] = "c"; +})(A || (A = {})); +var B; +(function (B) { + B[B["x"] = 0] = "x"; + B[B["y"] = 1] = "y"; + B[B["z"] = 2] = "z"; +})(B || (B = {})); +var value3 = A[B.x]; diff --git a/tests/baselines/reference/noUncheckedIndexAccess.symbols b/tests/baselines/reference/noUncheckedIndexAccess.symbols index 2f6c8a57061..b9317e08c6a 100644 --- a/tests/baselines/reference/noUncheckedIndexAccess.symbols +++ b/tests/baselines/reference/noUncheckedIndexAccess.symbols @@ -50,11 +50,35 @@ enum Meat { >value : Symbol(value, Decl(noUncheckedIndexAccess.ts, 14, 7)) >Meat : Symbol(Meat, Decl(noUncheckedIndexAccess.ts, 0, 0)) - const t = "testing" ->t : Symbol(t, Decl(noUncheckedIndexAccess.ts, 16, 7)) + const valueUndefined = "testing" +>valueUndefined : Symbol(valueUndefined, Decl(noUncheckedIndexAccess.ts, 16, 7)) - const value2 = Meat[t] + const value2 = Meat[valueUndefined] >value2 : Symbol(value2, Decl(noUncheckedIndexAccess.ts, 17, 7)) >Meat : Symbol(Meat, Decl(noUncheckedIndexAccess.ts, 0, 0)) ->t : Symbol(t, Decl(noUncheckedIndexAccess.ts, 16, 7)) +>valueUndefined : Symbol(valueUndefined, Decl(noUncheckedIndexAccess.ts, 16, 7)) + + enum A { +>A : Symbol(A, Decl(noUncheckedIndexAccess.ts, 17, 37)) + + a, b, c +>a : Symbol(A.a, Decl(noUncheckedIndexAccess.ts, 19, 10)) +>b : Symbol(A.b, Decl(noUncheckedIndexAccess.ts, 20, 6)) +>c : Symbol(A.c, Decl(noUncheckedIndexAccess.ts, 20, 9)) + } + enum B { +>B : Symbol(B, Decl(noUncheckedIndexAccess.ts, 21, 3)) + + x, y, z +>x : Symbol(B.x, Decl(noUncheckedIndexAccess.ts, 22, 10)) +>y : Symbol(B.y, Decl(noUncheckedIndexAccess.ts, 23, 6)) +>z : Symbol(B.z, Decl(noUncheckedIndexAccess.ts, 23, 9)) + } + + const value3 = A[B.x]; +>value3 : Symbol(value3, Decl(noUncheckedIndexAccess.ts, 26, 7)) +>A : Symbol(A, Decl(noUncheckedIndexAccess.ts, 17, 37)) +>B.x : Symbol(B.x, Decl(noUncheckedIndexAccess.ts, 22, 10)) +>B : Symbol(B, Decl(noUncheckedIndexAccess.ts, 21, 3)) +>x : Symbol(B.x, Decl(noUncheckedIndexAccess.ts, 22, 10)) diff --git a/tests/baselines/reference/noUncheckedIndexAccess.types b/tests/baselines/reference/noUncheckedIndexAccess.types index 3eab3e64bed..d50f53e442d 100644 --- a/tests/baselines/reference/noUncheckedIndexAccess.types +++ b/tests/baselines/reference/noUncheckedIndexAccess.types @@ -53,13 +53,38 @@ enum Meat { >Meat : typeof Meat >0 : 0 - const t = "testing" ->t : "testing" + const valueUndefined = "testing" +>valueUndefined : "testing" >"testing" : "testing" - const value2 = Meat[t] + const value2 = Meat[valueUndefined] >value2 : error ->Meat[t] : error +>Meat[valueUndefined] : error >Meat : typeof Meat ->t : "testing" +>valueUndefined : "testing" + + enum A { +>A : A + + a, b, c +>a : A.a +>b : A.b +>c : A.c + } + enum B { +>B : B + + x, y, z +>x : B.x +>y : B.y +>z : B.z + } + + const value3 = A[B.x]; +>value3 : string | undefined +>A[B.x] : string | undefined +>A : typeof A +>B.x : B.x +>B : typeof B +>x : B.x diff --git a/tests/cases/compiler/noUncheckedIndexAccess.ts b/tests/cases/compiler/noUncheckedIndexAccess.ts index 0891d9e40ae..826459036e5 100644 --- a/tests/cases/compiler/noUncheckedIndexAccess.ts +++ b/tests/cases/compiler/noUncheckedIndexAccess.ts @@ -17,5 +17,14 @@ enum Meat { //Avoiding a false positive const value = Meat[0] - const t = "testing" - const value2 = Meat[t] + const valueUndefined = "testing" + const value2 = Meat[valueUndefined] + + enum A { + a, b, c + } + enum B { + x, y, z + } + + const value3 = A[B.x]; \ No newline at end of file