As always, Luau is our new language that you can read more about at https://luau-lang.org.
While the team is busy to bring some bigger things in the future, we have made some small improvements this month.
Analysis improvements
We have improved tagged union type refinements to only include unhandled type cases in the else
branch of the if
statement:
type Ok<T> = { tag: "ok", value: T }
type Err = { tag: "error", msg: string }
type Result<T> = Ok<T> | Err
function unwrap<T>(r: Result<T>): T?
if r.tag == "ok" then
return r.value
else
-- Luau now understands that 'r' here can only be the 'Err' part
print(r.msg)
return nil
end
end
For better inference, we updated the definition of Enum.SomeType:GetEnumItems()
to return {Enum.SomeType}
instead of common {EnumItem}
and the return type of next
function now includes the possibility of key being nil
.
Finally, if you use and
operator on non-boolean values, boolean
type will no longer be added by the type inference:
local function f1(a: number?)
-- 'x' is still a 'number?' and doesn't become 'boolean | number'
local x = a and 5
end
Error message improvements
We now give an error when built-in types are being redefined:
type string = number -- Now an error: Redefinition of type 'string'
We also had a parse error missing in case you forgot your default type pack parameter value. We accepted the following code silently without raising an issue:
type Foo<T... = > = nil -- Now an error: Expected type, got '>'
Error about function argument count mismatch no longer points at the last argument, but instead at the function in question. So, instead of:
function myfunction(a: number, b:number) end
myfunction(123)
~~~
We now highlight this:
function myfunction(a: number, b:number) end
myfunction(123)
~~~~~~~~~~
If you iterate over a table value that could also be nil
, you get a better explanation in the error message:
local function f(t: {number}?)
for i,v in t do -- Value of type {number}? could be nil
--...
end
end
Previously it was Cannot call non-function {number}?
which was confusing.
And speaking of confusing, some of you might have seen an error like Type 'string' could not be converted into 'string'
.
This was caused by Luau having both a primitive type string
and a table type coming from string
library. Since the way you can get the type of the string
library table is by using typeof(string)
, the updated error message will mirror that and report Type 'string' could not be converted into 'typeof(string)'
.
Parsing now recovers with a more precise error message if you forget a comma in table constructor spanning multiple lines:
local t = {
a = 1
b = 2 -- Expected ',' after table constructor element
c = 3 -- Expected ',' after table constructor element
}