I don’t really see why you would need to use mock-OOP for this, it’s wrapping a already existing class but there’s just not enough to make it worthwhile. You’re basically adding nothing to the original which makes it kind of useless.
But, if you really want to, you can do something like this:
local HighlightMod = {}
HighlightMod.__index = HighlightMod
function HighlightMod.new(parent: BasePart|Model, data: {[string]: any}): {[string]: any}
--ignore if missing arguments
if not parent or not data then
error("Missing parameters to 'HighlightMod.new'. Please check your parameters passed.", 2)
end
--create mock-object
local self = setmetatable({}, HighlightMod)
self.Highlight = Instance.new("Highlight")
--data contains the properties for the highlight
for prop: string, value: any in next, data, nil do
if typeof(value) ~= typeof(self.Highlight[prop]) and typeof(self.Highlight[prop]) ~= "nil" then
error("Custom error telling the user one of the properties is incorrect", 2)
end
self.Highlight[prop] = value --assign the property
self[prop] = value --also assign it in our class table
end
self.Highlight.Parent = parent --assign parent
return self --return the highlight
end
--[[
example method with our table of properties and the highlight
this is just a quick example for listing these properties,
if you want an easier way where you could just use
a print statement you can modify the
__tostring metamethod
]]
function HighlightMod:ListProps()
for prop: string, val: any in next, self, nil do
if prop == "Highlight" then continue end
print("{")
print(` [{prop}]: {val}`)
print("}")
end
end
return HighlightMod
Example usage:
local HighlightMod = require(--[[path to the module]])
local ModdedHighlight = HighlightMod.new(workspace:FindFirstChildOfClass("Part"), {
["FillColor"] = Color3.fromRGB(85, 170, 0)
})
ModdedHighlight:ListProps()
What I meant when I said it’s not really worth it is to do with how little extra you are adding. While class-wrapping with mock-OOP can be really useful, for example in notification systems, it seems more hassle to create a OOP system for it, not to mention it’ll be worse on memory. It seems better to just use separate highlight instances and store them in a table {Player: Highlight}. Up to you, I just thought it seemed like more work.
Thank you for expanding on the type annotation, I only used a basic one for a quick example of the OOP system.
Adding on, it’s unnecessary to OOP-ify everything (I hope that’s a term.)
If not you’re expanding over the Highlight instance (by adding new properties/methods for custom behavior), it’s technically useless to make an OOP system for that.
Yes, type is a keyword.
It can be used to create custom types (like you saw). You can go through luau programming without even touching the concept of custom types.
Autocomplete is the words that shop up in studio as you type. So, if you ryped prin it would suggest print. You can press enter to use an autocomplete to finish your word.
Classes is basically you were trying to do in the first place. OOP stands for Object-Oriented Programming, and in this paradigm there are 2 things: a class and objects. Objects inherit from classes, so basically you define everything in the class. You can create objects using class constructors.
In some languages, it might look like this:
//JavaScript example
const Object = new Class(params)
But, Luau doesn’t support the OOP paradigm, which is also why i called it mock-OOP. We can create the same effect using metatables, which are just tables that control how other tables behave. The __index metamethod means we can redirect an object to the class when we call a function.
The class constructor in Luau typically uses .new as the name. It’s a function that sets up the structure for the table/object (see reply #2 to this topic).
We can create types for this and add them to our code:
export type Object = rawkeyof<Class> & {
--extra properties
}
--note this doesn't type solve correctly, which means
--the properties don't match up to what is type annotated. This would be for autocomplete.
--You can manually set types like this:
export type Object = {
["example"]: string -- key "example" is associated with a string
}
--now we can annotate them on to our constructor to automatically give objects the type
function Class.new(): Object --this means the function returns something of the given type
end