Intellisense writing off Module singleton as "never"?

Alright, so, I wanna make a singleton module that is accessible across all of the client, not just one localscript, but the main issue is that Module.Get() is seen as type “never” by Intellisense, therefore breaking autocomplete (because type “never” obviously does not have method self:Test()).

What I do know fixes this is using export type to help Intellisense see the type of the function, but that breaks function documentation, and I would very much like to keep function documentation.

If anyone knows how to get by this without sacrificing documentation, please tell me about it!

Module:

local SharedInstance = nil

local Module = {}
Module.__index = Module

-- connect to the shared module or create it if it hasn't been yet
function Module.Get()
	if SharedInstance then return SharedInstance end
	SharedInstance = setmetatable({}, Module)
	return SharedInstance
end

-- function that says hi!
function Module:Test()
	print("hi")
end

return Module

The module works as intended (to my knowledge; I tested it before posting this), it’s just Intellisense not working.

1 Like

I’m not too familiar with the technical details of intellisense/type checker, but you can manually define the return type of the function as

function Module.Get(): typeof(SharedInstance or setmetatable({}, Module))

or rewrite the code like this to fix it:

return SharedInstance or setmetatable({}, Module)
2 Likes

I figured out the issue; IntelliSense can’t properly infer the return type of Module.Get() when you directly return the result of setmetatable.
This updated Module.Get() works just fine without making IntelliSense trip:

function Module.Get()
	if not SharedInstance then
		SharedInstance = {}
		setmetatable(SharedInstance, Module)
	end
	return SharedInstance
end

The problem is/was that IntelliSense doesn’t know what you’re returning, so it takes the first return and shows its type.

To fix this, you either change your code like you did ( not recommended when you have a big function or more than 4 returns ), or you tell it what type you’re expecting ( @_nowodev first suggestion ) .

Scripts
-- The problem

local Object = {}
Object.Name = "none"

local number = 2

function Object.new()
	if number > 100 then return "" end
	
	return Object	
end

Object.new()
-- the fix

local Object = {}
Object.Name = "none"

local number = 2
-- or use: typeof(setmetatable({},Object))
-- if it was a metatable
function Object.new() : typeof(Object)
	if number > 100 then return "" end

	return Object	
end


Object.new()
-- if you're not sure what's the type (2 or more) but still want it to show

local Object = {}
Object.Name = "none"

local number = 2

function Object.new() : typeof(Object) & string
	if number > 100 then return "" end

	return Object	
end


Object.new()

I am replying after you’ve fixed it so you understand the underlying problem if you encounter a more complex version.

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