With the new type solver which includes globals like keyof, is there now a better way to do OOP compared to the following:
--!strict
-- LOCAL
local ExampleObject = {}
ExampleObject.__index = ExampleObject
-- CLASS
export type Class = typeof(setmetatable({} :: {
firstName: string,
lastName: string,
}, ExampleObject))
-- CONSTRUCTOR
function ExampleObject.new(): Class
local self = {
firstName = "firstName",
lastName = "lastName",
}
setmetatable(self, ExampleObject)
return self
end
-- METHODS
function ExampleObject.open(self: Class, useForce: boolean)
end
return ExampleObject
For example, is there a way define class properties only once instead of having to write them out twice (i.e. once under -- CLASS, and again under -- CONSTRUCTOR)?
local Class = {}
Class.__index = Class
function Class:Method(): number
return self.a + self.b
end
local function new()
local self = {
a = 10,
b = 20
}
type Self = typeof(Class) & typeof(self)
return setmetatable(self, Class) :: Self
end
return {new = new}
Works in the old type solver too
If you want something akin to a decorator, you can do something like this:
local function constructor<T, V, A...>(class: T, fn: (A...) -> V) -> (...: A...) -> T & V
return function(...)
local members = fn(...)
return setmetatable(members, class)
end
end
Then you can do this
--...
local new = constructor(Class, function()
return {
a = 10,
b = 20,
}
end
It’s a nice idea, but for my case won’t be as desirable because you lose type checking within the methods themselves, and the ability to use the Class type outside of the module
local Class = {}
Class.__index = Class
local function new()
local self = {
a = 10,
b = 20
}
return setmetatable(self, Class)
end
export type Class = typeof(new())
function Class.Method(self: Class): number
return self.a + self.b
end
return {new = new}
I dunno if this works but if it does thats pretty cool
--!strict
-- LOCAL
local ExampleObject = {}
ExampleObject.__index = ExampleObject
-- CONSTRUCTOR
function ExampleObject.new()
local self = {
firstName = "firstName",
lastName = "lastName",
testPropery = "hi",
}
type Self = typeof(ExampleObject) & typeof(self)
setmetatable(self, ExampleObject)
return self
end
-- CLASS
export type Class = typeof(ExampleObject.new())
-- METHODS
function ExampleObject.open(self: Class, useForce: boolean)
end
function ExampleObject.close(self: Class, useForce: boolean)
end
return ExampleObject