Recently I’ve been running into issues such as types seemingly not being recognized.
Here is an example of my problem:
--!strict
type State = "Standing"|"Running"
type StateInfoTable = {[State]:{Value1:number, Value2:number}}
local StateInfo:StateInfoTable = {
Standing = {Value1 = 10}, --No warnings even though 'Value2' is not present | No autofill
["Standing"::State] = {Value1 = 10}, --Warnings due to 'Value2' not being defined | Proper autofill
}
It seems I have to manually define what type the index is?
We discussed this when adding string literals to the type system, and at that moment concluded that there’s odd semantical issues with numbers around NaN that make this a little less useful, and for most cases of idiomatic code we’d like to see code use string literals instead of number literals anyway - iow the section “error catching and control flow” in your post should probably be using strings or booleans.
The one exception to this is what we sometimes refer to as “tuple tables” - a table of a fixed length that has different types for different indices (“finite table” section in your post). We don’t support it right now. We want to eventually support it, but notably this is not the same as supporting numeric literals, and wouldn’t “naturally” fall out of supporting numeric literals in the type system.
Hilarious you mention this right when I went on to this post to make a comment about this. It’s mildly annoying when you write something and you index similarly to tables and the type checking marks you on it. Maybe my coding habits are terrible and the type checker is telling me what not to do.
Are string interpolation optimizations going to be pursued in the near future?
The inherent improvements towards ergonomics/readability that the use of string interpolation carries shouldn’t come at the expense of runtime performance (to the degree at which it currently does).
It’d be much appreciated if we had a handful of table utility functions (these would go a long way), for example, a table.find overload which accepts a predicate function so it can satisfy a broad range of scenarios including ones where the table is not necessarily a continuous array.
Intended on including more than one example; however, less is more + a predicate func overload to table.find probably has the most merit.
I’m not aware of any plans to make performance improvements there.
You should share examples that show a large difference in performance (and not just ""..i vs `{i}` please)
table library methods are implemented in C.
A table.find method with a predicate will actually be slower than Luau implementation because of C->Luau->C transitions for each predicate call.
For this reason, table.foreach and table.foreachi are marked as deprecated now, loop is way better for performance.
There is of course an argument for usability, not performance.
For that, you can just write your own module with helper functions and maybe even share it with the community so that other people don’t have to reimplement the same things.
Maybe we will have a better way to share Luau libraries in the future and provide some Roblox-made starter packs as well, but I can’t guarantee that at current point in time.
local test = {}
test.__index = test
test.value = "hello"
function test.new()
local self = setmetatable({}, test)
return self
end
function test:GET()
self.
end
return test
self. still doesn’t auto complete and suggest me “value”
Bro the thing yall needa add is, if a nil “self” is detected in a function and is element of a table, then it becomes a Table:FunctionName rather then the conventional Table.FunctionName (which doesn’t pass in self automatically)
I can’t go into details why this is important to me, but it really will makes things easier to case check both function and self containing functions
In the meantime, here’s my method I use to type idiomatic classes:
local Class = {}
Class.__index = Class
Class.Static = "Hello, world!"
type self = {
Value: number
}
export type Class = typeof(setmetatable({} :: self, Class))
function Class.new()
local self = setmetatable({} :: self, Class)
self.Value = 1
return self
end
function Class.Method(self: Class)
print(self.Static)
return self.Value
end