Linter incorrectly warns when indexing a dictionary when the key is defined from string literals

Here are the current cases where the linter warns or doesn’t warn

--!strict

type literals = "foo" | "bar" | "foobar"

local example: {[literals]: string} = {
	foo = "food",
	bar = "bard",
	foobar = "foodbard",
}

local a: "foo" = "foo"
print(example[a]:len()) --> valid

local b = "foo"
print(example[b]:len()) --> invalid

print(example["foo"]:len()) --> invalid

print(example.foo:len()) --> invald

Expected behavior

Here is what should and should not be warned

--!strict

type literals = "foo" | "bar" | "foobar"

local example: {[literals]: string} = {
	foo = "food",
	bar = "bard",
	foobar = "foodbard",
}

local a: "foo" = "foo"
print(example[a]:len()) --> valid

local b = "foo"
print(example[b]:len()) --> invalid

print(example["foo"]:len()) --> valid

print(example.foo:len()) --> valid

The difference between what I expect to happen and what happens is with the last two cases:

-->> undesirable
print(example["foo"]:len()) --> invalid
print(example.foo:len()) --> invalid

-->> desirable
print(example["foo"]:len()) --> valid
print(example.foo:len()) --> valid

I’d expect the linter to understand that indexing dictionaries with the dot operator or square brackets is guaranteed to be a string literal, and should be treated as such.

5 Likes

We’ve filed a ticket into our internal database for this issue, and we will update you when we have further information!

Thanks for the report!