I looked and saw this hacky way of getting over cyclic dependency to get types into modules and was wondering if anyone can help me to get it working for OOP compositions???
The way to do it:
Example (signal.lua):
local package = script.Parent.Parent
local packages = package.Parent
type SignalModule = typeof(require(packages.signal))
local getModule = require(package.utilities.getModule)
local signalModule = getModule("signal")
-- i hate this
export type Connection = typeof((function()
local module = require(packages.signal)
return {} :: module.Connection
end)())
export type Signal<T...> = typeof((function()
local module = require(packages.signal)
return {} :: module.Signal<T...>
end)())
return require(signalModule) :: SignalModule
Car.lua
local Engine = require(script.Engine)
local Car = {}
Car.__index = Car
type self = {
["_Engine"]: Engine,
Speed: number
}
type Car = typeof( setmetatable({}, Car) )
export type Car = typeof( setmetatable({} :: self, Car) )
function Car.new(): Car
local self = setmetatable({} :: self, Car)
self._Engine = Engine.new()
self.Speed = 15
return self
end
function Car.Boost(self: Car): ()
self.Speed += 50
end
return Car
Engine.lua
export type Car = typeof((function()
local module = require(script.Parent)
return {} :: typeof(module.new())
end)())
local Engine = {}
Engine.__index = Engine
type self = {
Speed: number
}
type Engine = typeof( setmetatable({}, Engine) )
export type Engine = typeof( setmetatable({} :: self, Engine) )
function Engine.new(Car : Car): Engine
local self = setmetatable({} :: self, Engine)
self.Speed = 15
return self
end
return Engine
What am I missing?
Here in the parameter (Car : Car) just resolves to any type when it should resolve to Car type:
function Engine.new(Car : Car): Engine
local self = setmetatable({} :: self, Engine)
self.Speed = 15
return self
end
More info: Guide to Type-Checking with OOP
@MagmaBurnsV posted about this method and I wanted to adopt it so that I can compose objects inside of each other. Anyone have any ideas please? Any help is appreciated, thanks!
You could establish a new module and put all your types into that module so it can be used across all your classes
*Edit
Also im quite confused why you would need to pass in the car class into the engine class as it isnt currently being used
I am having trouble understanding what you mean. Is this possible???
Types.lua (has the types):
local module = {}
local Engine = {}
Engine.__index = Engine
type EngineSelf = {
HorsePower: number
}
type Engine = typeof(setmetatable({}, Engine))
export type Engine = typeof(setmetatable({} :: EngineSelf, Engine))
function Engine.new(): Engine
local self = setmetatable({} :: EngineSelf, Engine)
self.HorsePower = 15
return self
end
module.Engine = Engine
local Car = {}
Car.__index = Car
type CarSelf = {
_Engine: Engine,
Speed: number
}
type Car = typeof(setmetatable({}, Car))
export type Car = typeof(setmetatable({} :: CarSelf, Car))
function Car.new(): Car
local self = setmetatable({} :: CarSelf, Car)
self._Engine = Engine.new()
self.Speed = 15
return self
end
function Car.Boost(self: Car): ()
self.Speed += 50
end
module.Car = Car
return module
In Car.lua, how would I fetch the Engine type from that?
local Types = require(script.Parent.Types)
local Engine = require(script.Engine)
local Car = {}
Car.__index = Car
type self = {
["_Engine"]: Engine,
Speed: number
}
type Car = typeof( setmetatable({}, Car) )
export type Car = typeof( setmetatable({} :: self, Car) )
function Car.new(): Car
local self = setmetatable({} :: self, Car)
self._Engine = Engine.new()
self.Speed = 15
return self
end
function Car.Boost(self: Car): ()
self.Speed += 50
end
return Car
It is a bit messy but it is a proof of concept. I am looking to compose objects in objects and just did that to test if it would work but I am trying to get it to work. What do you think of the above, can we do this to get the Types or did I do it wrong? Bit sloppy but I tried.
Sorry for the late response I kind of fell asleep
im pretty sure the Engine type would already be inside of car.lua if you used Engine.new() because Engine.new() returns an Engine object of the Engine type.
if your asking for the literal type you could just export the engine type
-- a module that holds all the types
export type Engine = {
HorsePower: number
}
export type Car = {
_Engine: Engine
Speed: number
}
-- car module
-- if you want to fetch the engine type you could do it liike this
local types = require(--[[path to type module]])
type Engine = types.Engine