Classes and types don’t mix well in Luau.
Types don’t have proper metatable support, and since the common Luau class syntax depend on them, issues appear left and right, unknown, unpredicted types, it’s painful.
The method for building classes was highlighted to me by @Elttob on Fusion Friday. I’ve known this method existed for a while, but it was unviable because of performance concerns.
Since then, Luau has introduced function “caching”, meaning if a function is the same and follows some rules, it will not waste more memory because of it.
What is this method?
This method doesn’t involve metatables at all. It simply just depends on the fact that this new function caching optimization now exists, which makes this much, much more viable.
This is how you will build a class using this method.
export type Class = {
Public: number,
Changed: ScriptSignal.ScriptSignal,
_private: number,
Add: (Class, number) -> ()
}
local function Class(): Class
local self = {
Public = 0,
Changed = Signal(),
_private = 0
}
function self:Add(number) -- Inferred!
local result = self._private + number
self._private = result
self.Public = result
self.Changed:Fire()
end
return self
end
One note is that creating new objects is slower.
Need to confirm: Indexing methods is faster because we store methods on the table itself, not having to pass through __index
.
Anyway, this has been it. I found this method for creating classes really nice and wanted to show it off to other developers searching for type friendlier code!
It’s nice to highlight that Luau is thinking about getting class syntax which would solve the issues with types. Meanwhile, we have this, which is also a very elegant solution.
Note: You can wrap these functions in tables and call it .new
if you wanna be consistent with Roblox’s APIs.