Luau Recap: July 2021

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

2021-08-03-05-55-45-478

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

2021-08-03-06-00-10-888

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.

2 Likes

I believe a “sweeter” way of getting around this is with the type casting operator (str = t.foo :: string)

This should definitely be fixed but that might be a cleaner way of getting around it.

4 Likes

This is known and is on the shortlist of planned improvements.

3 Likes

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:

local x: () -> number? = callback

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

1 Like

Will we still be able to script in Lua?

1 Like

Luau is syntactically backwards compatible with Lua 5.1. So yes, all Lua 5.1 code you wrote is still valid Luau code.

1 Like

Thank you for the report, a fix for this will be included in the next update.

3 Likes

Equality comparison between nullable and non-nullable type should probably be allowed?
image

3 Likes

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.