Guide to Type-Checking with OOP

I omitted it for simplicity of the example but it’d look something like this if I wrote them:

type PrivateVariables = {
    name: string -- yippee! type safety 
}

loca privateVariables: { [Something]: PrivateVariables } = {}

local Something = {}
Something.__index = Something

function Something.new(): Something
     local self = setmetatable({}, Something)

    self.nothing = nil

    privateVariables[self] = {
        name = name,
    } -- tadaaaa
    
    return self
end

type Something = typeof(Something.new(…)) -- right under new, before methods

function Something.doSomething(self: Something): ()
    privateVariables[self].name = 2 -- type warning! i think… i’m on mobile so i can’t test it
end

return Something
5 Likes

nice tutorial. Is there a way to access created types from modules? I use module.Type and it sort of works but I can access things like .__index

Adding export before a type makes it accessible under the namespace the module gets required by.

-- Module.luau
export type MyType = number
return nil

-- Server.luau
local MyModule = require(Module.luau)
local A: MyModule.MyType = 1

Unfortunately having .__index exposed is a side effect of capturing the whole class table as a metatable.

However, you can set Car.__index to just a new table and then put the methods inside it. It wastes more memory, but it fixes your problem.

local Car = {}
Car.__index = {}

-- Same Stuff...

function Car.__index.Boost(self: Car): ()
	self.Speed += 50
end
1 Like

guess I gotta cope lol. anyway thanks

I just predefined the entire module script as a type in a separate module underneath the module script and require it for typing.

So tedious but looks cleaner imo, and let’s u really think ab what ur coding.

Pre defining your object data table and the object module

I found other way to do this (but non index)

local hi = {}

function hi.new()
	local b = {}
	b.Sick = 1
	b.run = "hi"
	function b:Rap()
		print("RAPPIN'")
	end
	
	function b.No()
		print("uhh")
	end
	
	return b
end

export type raiter = typeof(hi.new(...))
return hi

And also with double types:

local system = {}

function system.new()
	local base = {}
	
	local private = {}
	
	function base.newEnumerator()
		local h = {}
		h.NNn = 1
		return h
	end
	
	export type EnumerateCall = typeof(base.newEnumerator())
	
	return base
end

export type SystemCall = typeof(system.new(...))

return system
1 Like