Strange type-checking behaviour?

So, i was writing debug utility and suddenly strange warn line (or how does it called) from type-checking appeared.

function DEBUG_UTILITY:DRAW_TAG_QUICK(DISPLAY_TAG : string, VALUE : any, LIFETIME : number)
	-- code for tracebacking.
	
	DEBUG_UTILITY:DRAW_TAG(`{THREAD}:{LINE_NUMBER}:{DISPLAY_TAG}`, DISPLAY_PATH, VALUE, LIFETIME or 0.2, tonumber(LINE_NUMBER))
end
function DEBUG_UTILITY:DRAW_TAG(DISPLAY_TAG : string, DISPLAY_PATH : string, VALUE : any, LIFETIME : number, LINE_NUMBER : number)
-- LIFETIME works without any issues.
end

and another function:

function DEBUG_UTILITY:DRAW_LINE(DISPLAY_TAG : string, LIFETIME : number?, ZINDEX : number?, LINE_COLOR : Color3?, THICKNESS : number?, DIRECTION : Vector3, ORIGIN : Vector3, ORIGIN_TEXT : string?, TARGET_TEXT : string?)
	if not DEBUG_ENABLED then
		return
	end
	
	if IS_SERVER and CurrentCamera.ViewportSize.Magnitude < 10 then
		return
	end
	
	LINE_COLOR = LINE_COLOR or Color3.new()
	LIFETIME = LIFETIME or 0.2
	ZINDEX = ZINDEX or 1
	THICKNESS = THICKNESS or 1.5
	ORIGIN_TEXT = ORIGIN_TEXT or ``
	TARGET_TEXT = TARGET_TEXT or ``
	
	if DEBUG_CONFIGURATION.DEBUG_LINES_AS_TAGS then
		-- traceback

		DEBUG_UTILITY:DRAW_TAG(`{THREAD}:{LINE_NUMBER}:{DISPLAY_TAG}`, DISPLAY_PATH, ORIGIN, LIFETIME, tonumber(LINE_NUMBER))
	end

Has anyone encountered this and managed to fix it?

pretty sure this isn’t an actual bug in your code, just a false positive from the type checker. LIFETIME is already typed as non-optional number so it can’t realistically be nil, but the solver seems to lose track of that once it crosses into a colon method call like DRAW_TAG, this kind of thing happens with or default patterns and self calls on the newer type solver

fix is easy though, just pull LIFETIME or 0.2 out into its own local variable before the call instead of writing it inline, so something like local finalLifetime = LIFETIME or 0.2 then pass finalLifetime into DRAW_TAG. that usually gets the checker to actually narrow the type properly. if it still complains after that you can just force it with a type assertion like (LIFETIME :: number) at the call site, not the cleanest but it works

either way your code should run totally fine at runtime, this is purely the linter being wrong, nothing you need to actually fix logic wise

1 Like

interesting thing is, calling DRAW_TAG using self removes this warning:
self:DRAW_TAG
:thinking: