Found another issue with the type checker! Is this the right place?!?
Seems like your type constraint resolver doesn’t properly handle table (or Instance) properties when inferring types. They do not respect conditional logic whatsoever, which is annoying since I don’t want to create a variable just to reference a property I hardly ever use.
--!strict
local basepart: BasePart
local model: Model = Instance.new("Model")
assert(model.PrimaryPart, "Model must have a PrimaryPart!")
basepart = model.PrimaryPart
In this case, model.PrimaryPart is inferred as BasePart? when it should be BasePart since it passes the assert call earlier on.
This applies to tables as well:
--!strict
local t: { foo: string? } = { foo = nil }
local str: string
if t.foo then
str = t.foo
end
As said before, an easy way to solve this is by using a variable. However, this is a minor inconvenience with rarely-used properties that often don’t require caching.
Found a minor bug with the way types are displayed.
This code should be perfectly sound, and indeed emits no warnings:
--!strict
local alwaysReturnsANumber = function() return 2 end
local sometimesReturnsACallback = function(): typeof(alwaysReturnsANumber)?
if math.random() > 0.5 then
return alwaysReturnsANumber :: any
else
return nil
end
end
local callback = sometimesReturnsACallback()
if callback then
local number = callback()
print(number + 3)
end
However, whenever I hover over the type of the variable callback (via the “Luau-Powered Type Hover” beta feature), it tells me that callback is of type () -> number?
This means that the callback definitely exists and will optionally return a number. It should really be displayed as (() -> number)? since it is optionally a callback that always returns a number.
This has confused me on multiple occasions. Adding the following line to the end of that code will lead to a funky looking warning:
Type '() -> number?' could not be converted into '() -> number?'
Obviously, this is just a display issue, and it really should be saying Type '(() -> number)?' could not be converted into '() -> number?' or vice-versa