Missing entries on a type-annotated table type no longer emits a warning

Reproduction Steps
Type the following code into a script:

--!strict
-- Example1

type MyType = {
	property1: string,
}

local x: MyType = {
	property1 = "Hello",
	property2 = "This should emit a warning",
}

Alternative example:

--!strict
-- Example2

type MyType = {
	property1: string,
}

local function takesMyType(x: MyType)
	print(x)
end

takesMyType({
	property1 = "Hello",
	property2 = "This should emit a warning",
})

Expected Behavior
This code used to emit a warning that the table “x” has an extra property “property2”, which was super useful when writing interfacing luau code.

Actual Behavior
No warning is emitted, even though x has an extra property. This means calling functions like “takesMyType” with an extra property can lead to confusion when writing interfacing code, since you will have added a property that should not exist, yet there are no warnings emitted.

Issue Area: Studio
Issue Type: Other
Impact: High
Frequency: Constantly
Date First Experienced: 2022-03-23 00:03:00 (-06:00)
Date Last Experienced: 2022-03-23 00:03:00 (-06:00)

1 Like

This one is tricky, because there are examples a lot like it which should not generate errors. For example

-- Example3
local x = {
	property1 = "Hello",
	property2 = "Should this emit a warning?",
}
takesMyType(x)

or

-- Example4
local x = {
	property1 = "Hello",
	property2 = "This should not emit a warning",
}
takesMyType(x)
print(x.property2)

Differentiating between these examples is tricky. Example4 definitely shouldn’t error. Getting Example3 to error is complicated (it would need some kind of analysis to determine that property2 is irrelevant, which we’re not doing at the moment). Example3 is just the same as Example2 but with a binder.

The old implementation was unsound unfortunately. The fix (and this problem) is duscussed at https://github.com/Roblox/luau/blob/master/rfcs/sealed-table-subtyping.md#drawbacks

3 Likes

Hmm… I noticed that tables without an index type are now not iterable the same way they used to be, so I can see how this might be intentional behavior. I really wish Luau could embrace adding a few built-in generic types like TypeScript does (e.g. Partial<T>, or something like Strict<T> for this use case). For something like Pract components (my React-like library), having this level of strictness is very useful.

Thanks for the detailed response regardless though :heart:

Since all of my work is done in Roblox Studio, it’s hard to keep up with the luau github since it’s usually much further ahead than Roblox Studio feature-wise.

Just following up!

I’m closing this thread since this is an intended behavior.
If you come across any other issues, please make a new post.

Thanks for the report!

1 Like