Typechecking: How would you change an expected parameter type depending on the value of a previous argument

Hi,

So I’m just wondering how I would go about changing a function’s expected parameter type depending on some other parameter?

In my example I’m working with a folder of different values which relate to certain round stats (eg. round time, round status etc), all of which are different types of value bases. So, suppose you go about approaching it by creating a module to set these values instead of just setting it manually (works better with my workflow):

local module = {}

function module:SetRoundStat(statName: 'RoundStatus' | 'TimeRemaining', value: any)
    gameStats:FindFirstChild(statName).Value = value
end

Okay, so that’s what I’m fine with thus far. However, as “RoundStatus” is a stringvalue, and “TimeRemaining” is an intvalue, I would like to have the value parameter of my function to change to either string or number depending on whether statName is “RoundStatus” or “TimeRemaing”, instead of just “any”. Is this possible?

Update:

try this. Set as solution if it works

local module = {}

function module:SetRoundStat(statName: 'RoundStatus' | 'TimeRemaining', value: any)
    local stuff_to_change = gameStats:FindFirstChild(statName)
    if not stuff_to_change then return end
    if stuff_to_change.Name == 'RoundStatus' then
        value = value:tostring() 
    elseif stuff_to_change.Name == 'TimeRemaining' then
        value = value:tonumber()
    end
    stuff_to_change .Value = value
end

I mean when I go to call the function from another script, the expected type of ‘value’ would change depending on what statName is.

Using your method, it still defaults back to any.

	function module:SetStat(stat: 'RoundStatus' | 'TimeRemaining', value: any)
		local stuff_to_change = gameStats:FindFirstChild(stat)
		if stuff_to_change.Name == 'TimeRemaining' then
			value = tonumber(value) :: number
		end
		stuff_to_change.Value = value
		return module
	end

Taking from the other examples provided and adding my own modification to it.

It’s not perfect but it looks like it’ll get the job done.

function setState(stat: 'RoundStatus' | 'TimeRemaining', value: ('RoundStatus' & string) | ('TimeRemaining' & number))```

That just seems to assign the type “‘TimeRemaining’ & number” to value. I was thinking of doing something similar though, by doing:

value: typeof(stat == 'RoundStatus' and 'string' or 1)

but that seems to just assign type ‘string | number’ to value :thinking:

to my knowledge i dont think that is possible. I believe once it has been declared, it cant be changed

Okay I was actually able to get pretty close by using &


image

    module.SetStat = function(self, stat, value)
		local stuff_to_change = gameStats:FindFirstChild(stat)
		stuff_to_change.Value = value
		return module
	end :: 
	((self: module, stat: 'RoundStatus', value: string) -> (module)) & 
	((self: module, stat: 'RunnersRemaining' | 'TotalCars' | 'TimeRemaining', value: number) -> (module))

The only thing is that it doesn’t auto-select the appropriate option. Anyone have any ideas for that?

Did you get anywhere with this, I came across the same issue recently

Whoops sorry for the extremely late response but no sadly.