I want to create a table with an assigned metatable inherit methods from another metatable. Assume that we’re using the --!strict type solver here.
Let’s say you have a type and table of properties.
type properties = {
name: string,
power: number,
walking: boolean
}
local properties: properties = {
name = "norman",
power = 4,
walking = false
}
And then you have a table of methods and a class type.
local methods = {}
methods.__index = methods
type object_class = typeof(setmetatable({} :: properties, methods))
methods.start_walking = function(self: object_class)
self.walking = true
print(self.name.." is walking!")
end
You create a class type object by assigning the methods table to the properties table with setmetatable.
local object: object_class = setmetatable(properties, methods)
Works fine, right?
object:start_walking() -- "norman is walking!"
Now, let’s say that you want to add extra methods and an inherited class type.
local cool_methods = {}
cool_methods.__index = cool_methods
setmetatable(cool_methods, methods) -- build on top of existing methods
type cool_object_class = typeof(setmetatable({} :: properties, cool_methods))
cool_methods.do_a_flip = function(self: cool_object_class)
self.power += 2
self.walking = false
print(self.name.." did a flip, woah!")
end
You create the inherited class type object, but…
local cool_properties: properties = {
name = "coolio",
power = 2,
walking = false
}
local cool_object: cool_object_class = setmetatable(cool_properties, cool_methods)
cool_object:start_walking()
cool_object:do_a_flip()
The methods aren’t available in autocompletion despite being there!!!
Full Script
--!strict
--// Base Object
-- properties
type properties = {
name: string,
power: number,
walking: boolean
}
-- methods
local methods = {}
methods.__index = methods
type object_class = typeof(setmetatable({} :: properties, methods))
methods.start_walking = function(self: object_class)
self.walking = true
print(self.name.." is walking!")
end
-- creation
local properties: properties = {
name = "norman",
power = 4,
walking = false
}
local object: object_class = setmetatable(properties, methods)
object:start_walking() -- "norman is walking!"
--// Inherited Object
-- methods
local cool_methods = {}
cool_methods.__index = cool_methods
setmetatable(cool_methods, methods) -- build on top of existing methods
type cool_object_class = typeof(setmetatable({} :: properties, cool_methods))
cool_methods.do_a_flip = function(self: cool_object_class)
self.power += 2
self.walking = false
print(self.name.." did a flip, woah!")
end
-- creation
local cool_properties: properties = {
name = "coolio",
power = 2,
walking = false
}
local cool_object: cool_object_class = setmetatable(cool_properties, cool_methods)
cool_object:start_walking()
cool_object:do_a_flip()
That leaves me with a few questions…
Is this intentional? Is there a better method for creating class inheritance in Roblox? Should I even use metatables for OOP in the engine?
Let me know what you think, and thanks for reading ![]()



