Character OOP Type Error Help

Hello! I’m having issues with Type Errors in a module script I’m writing. I’m kind of new to strictly-typed lua, and I’m not sure if this is just something I should ignore or put more thought/effort into.

On line 53, when I call self:destroy(), I get a type error stating: Type 'RBXScriptConnection' could not be converted into 'nil' in an invariant context. I also get a type error on line 77, when I run this code: self.died_connection = nil. This error says: Type 'nil' could not be converted into 'nil&~(false?)'; this is because in the 1st component of the intersection, the negation `false`, and `nil` is not a subtype of `false?`

No matter what I do, I can’t get the type errors to go away. I’m not sure if I should just live with the red underlines or try to find the root cause.

--!strict

-------------- 
-- SERVICES -- 
-------------- 
local Players = game:GetService("Players")

--------------- 
-- CONSTANTS -- 
--------------- 

----------- 
-- TYPES -- 
----------- 
export type characterObj = {
	model: Model,
	humanoid: Humanoid,
	animator: Animator,
	player: Player?,
	died_connection: RBXScriptConnection
}

--------------- 
-- VARIABLES -- 
--------------- 

------------ 
-- MODULE -- 
------------ 
local CharacterService = {}
CharacterService.__index = CharacterService

----------------------- 
-- PRIVATE FUNCTIONS -- 
----------------------- 

--------------------- 
-- PRIVATE METHODS -- 
--------------------- 

---------------------- 
-- PUBLIC FUNCTIONS -- 
---------------------- 
function CharacterService.new(character: Model): characterObj
	local self = setmetatable({}, CharacterService)

	self.model = character
	self.humanoid = character:WaitForChild("Humanoid") :: Humanoid
	self.animator = self.humanoid:WaitForChild("Animator") :: Animator
	self.player = Players:GetPlayerFromCharacter(character) :: Player?

	self.died_connection = self.humanoid.Died:Connect(function()
		self:destroy()
	end)

	return self
end

function CharacterService.init(): ()
	-- placeholder
end

function CharacterService.start(): ()
	-- placeholder
end

-------------------- 
-- PUBLIC METHODS -- 
-------------------- 
function CharacterService:destroy()
	if self.model then
		self.model:Destroy()
	end

	if self.died_connection then
		self.died_connection:Disconnect()
		self.died_connection = nil
	end

	self.model = nil
	self.humanoid = nil
	self.animator = nil
	self.player = nil
end

--------------- 
-- EXECUTION -- 
--------------- 

------------- 
-- CLOSING -- 
------------- 
return CharacterService

Again, I’m new to using type annotations and OOP structures in Roblox. Thanks for your patience and responses
- P_rceptionNull (Noxira)

1 Like

The issue might be that your characterObj type defines properties like died_connection as non-nil, but you’re trying to set them to nil in the destroy() function. Adding ? to the types (like RBXScriptConnection?) should fix the errors by allowing them to be nil.

Make sure to disconnect your connection in Destroy().

function CharacterService:Destroy()
    -- Add any other cleanups for objects
    -- For example, if you had a part you created in the constructor, do self.Part:Destroy()
    self.died_connection:Disconnect()

    table.clear(self) -- This just sets all values inside a table to nil (in this case clearing itself)
end

You got this error because it was trying to set self.died_connection to nil while it was still connected.
Just properly clean up any objects with their Destroy() method, and clear everything else.

Also, partially unrelated, but you should add your instance methods to the type:

export type CharacterService = {
    model: Model,
    humanoid: Humanoid,
    animator: Animator,
    player: Player?,
    died_connection: RBXScriptConnection,
    init: () -> (), -- First set of parentheses represents method parameters, second set represents what it returns.
    start: () -> (),
    destroy: () -> (),
}

This worked, thank you. I’ll also look into your other post.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.