Help with OOP inheritance and Type Casting

I need support on how to use OOP inheritance and type casting, look down for more info.

Main Module:

--!strict

export type BatObject = {
	Force: number,
	name: string,
	frequency: number,
	User : Player,
	id: string,
	Components:{}

}

type BatConstructor = {
	__index: BatConstructor,
	create: (Attributes : BatObject) -> BatTemplate,
	_createcomponent: (self: BatTemplate, Module : ModuleScript) -> (),
	_createcomponents: (self: BatTemplate) -> (),
}

local BatTemplate : BatConstructor = {} :: BatConstructor
BatTemplate.__index = BatTemplate
export type BatTemplate = typeof(setmetatable({} :: BatObject, {} :: BatConstructor))
local componentsModules = {}
local Combat = componentsModules["Combat"].Combat
local SetupBat = componentsModules["SetupBat"].SetupBat
local InputHandler = componentsModules["InputHandler"].InputHandler

type components = {
	Combat: Combat,
	SetupBat: SetupBat,
	InputHandler: InputHandler
}


local HttpService : HttpService = game:GetService("HttpService")
function BatTemplate.create(Attributes : BatObject)
	local self = setmetatable({} :: BatObject, BatTemplate)
	self.User = Attributes.User
	self.Force = Attributes.Force
	self.name = Attributes.name
	self.frequency = Attributes.frequency
	self.id = HttpService:GenerateGUID()
	self:_createcomponents()
	self.Components = {} :: components
	return self	
end

function BatTemplate:_createcomponent(Module : ModuleScript) -- require module, create object, put component in table
	local Required = require(Module) :: any
	if Required["create"] then
		local Object = Required.create(self)
		self.Components[Module] = Object
		componentsModules[Module] = Required
	else
		warn(Module.Name.." [#001] INVALID COMPONENT FORMAT")
	end 
end

function BatTemplate:_createcomponents()
	for _,module in script:GetChildren() do
		if module:IsA("ModuleScript") then
			self:_createcomponent(module)
		else
			warn(module.Name.." [#001] INVALID COMPONENT FORMAT")
		end
	end
end

return BatTemplate

Component named setup:

--!strict
type SetupObject = {}

type SetupClass = {
	__index: SetupClass,
	create: (BatTemplate : any) -> SetupBat
}

local SetupBat = {} :: SetupClass
SetupBat.__index = SetupBat
export type SetupBat = typeof(setmetatable({} :: SetupObject, {} :: SetupClass))

function SetupBat.create(BatTemplate)
	local self = setmetatable({} :: SetupObject, SetupBat)

	return self
end

return SetupBat

Now, my problem is that I don’t know how to place the components in the table in a way that the auto completion and other typecasting benefits affect it, ive tried that way but it didnt work as intended.

second, I do not know how to use the type of my main module in a component for auto completion without requesting it again, which i found out that brings errors.

If someone can explain how i could fix these problems, it will be greatly appreciated.

I don’t understand what your problem is. Can you rephrase your problem?

You can do this by the way:

typeof(require(module)) --> Module's return type

Essentially what I’m trying to achieve is auto completion for all my components and also the components to have access to the main module’s type ( which is the exported type BatTemplate ) holding both constructor methods and the properties. My issue is that I don’t know how to achieve that without REQUESTING the main module again, because if I do that to extract the type exported the script errors because it’s being required by a server script already. Hope that clears it up

1 Like