Yeah I really loved the condition already being checked update. This is helpful in reducing lag as well as unnecessary code.
The table operations update confused me a little bit at first but adding parenthesis did indeed remove the annoying little tick under the table addition.
I reported a bug in February in the Luau linter, where if you index script.NameGoesHere, it will show that “Key ‘NameGoesHere’ not found in class ‘Script’” if there is no such Instance when the line of code is written, but even after inserting something named “NameGoesHere” it just won’t go away until restarting Studio.
The new linter improvements are great, but please fix this or tell us that there’s something that prevents an easy fix. It’s very distracting, and the only reason I don’t have the “Scripts Are Non-Strict by Default” beta on.
Little tip—you can actually drag the script up in the explorer (reparenting it to something else), and then drag it back to where it was to refresh the linter and get rid of these warnings. I usually do this whenever I’m referencing children of scripts which I add as I write the code, and I have strict mode on all of my code right now.
It is annoying how some warnings can cache like this though.
task.wait seems to be implemented for testing, wondering if there’s any plans to make it better for mass use, even though polling is bad of course, I guess there’s people that need heavy usage, and even task.wait from my understanding shouldn’t be fixing the entire wait lagging with multiple threads being resumed and yielded at once,
This looks great! I’ll keep waiting for luau to have destructuring dictionaries syntax like that of Javascript
Something like:
local names = {
["harry"] = {
location = "usa",
age = 17
},
["bob"] = {
location = "canada",
age = 14
}
}
local { harry, { age } } = names -- data of harry and age of bob destructured.
The biggest difference isn’t so much the precision, it’s the fact that it doesn’t throttle: task.wait(delay) will unsuspend after the delay regardless of what the consequences may be, compared to wait(delay) which “helpfully” throttled execution for you, sometimes delaying resumption by extra frames to keep the frame rate smooth (something which frequently frustrated devs because they didn’t have much control over the throttling).
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