Luau type warnings - Custom class

I’m trying to make a custom class to manage databases (DatabaseManager.lua).
Unfortunatelly I encountered an issue while doing so: Luau types.
I could just dont use any types and do it all dynamically but then I wouldnt have any intellisense and all that fancy features.

-- !strict

export type DSClass = {
	__raw: GlobalDataStore
}

local DSClass = {}
DSClass.__index = DSClass

DSClass.new = function(datastore: GlobalDataStore): DSClass
	local class: DSClass = {} :: DSClass
	setmetatable(class, DSClass)
	
	class.__raw = datastore
	
	return class
end

image


If I remove :: DSClass and just leave it as it is then this error appears
image


If I make class a typed variable (local class: DSClass = {}) then this error appears alongside Type 'DSClass' could not be converted into 'DSClass'
image


Statically defining __raw during declaration does not remove Could not be converted into error (local class: DSClass = { __raw = datastore })

Change the type declaration to:

export type DSClass = typeof(setmetatable({}, DSClass))

and put it under the DSClass metamethod decleration.

The types are confliciting becuase your local variable has a metatable, this means its type is different despite having all the fields of DSClass. As stated by @TheRealANDRO you can declare a type with a metatable by chaining typeof and setmetatable.

The following is considered type sound.

--!strict

local DSClass = {}
DSClass.__index = DSClass

export type DSClass = typeof(setmetatable({} :: {
	_raw: GlobalDataStore
}, DSClass))

function DSClass.new(datastore: GlobalDataStore): DSClass
	return setmetatable({
		_raw = datastore
	}, DSClass)
end
1 Like