I have multiple functions in my code which have typed variadic arguments.
Example:
function module.addCallback<P3...>(self: schema, fn: (P3...) -> (), ...: P3...)
assert(type(fn) == "function")
table.insert(self._callbacks, {
fn = fn,
args = table.pack(...),
})
end
I had to name them ‘P3’ instead of just ‘P’ because in my object I use P for other functions. It appears that when this gets compiled into one big type, the P variable is getting shared with other types. I am not certain how this is playing out, but I will include the source code. It seems like one named type is poisoning the rest of them within a super-type.
--!strict
local module = {}
export type schema_raw = {}
export type schema = typeof(setmetatable({}, { __index = module })) & schema_raw
function module.new(): schema
local self: schema = setmetatable({}::any, {__index = module})
return self
end
function module.exec<P..., R...>(
self: schema,
fn: (schema, P...) -> ((number | string | boolean)?, R...),
...: P...
): (number | string, R...)
local reason = 0
local results = { true, true }
return reason, table.unpack(results::{any}, 3)
end
function module.ParseResult<R...>(
reason: number | string,
...: any --- This really should be R... but it does not work at all
): (boolean, string?, R...)
if type(reason) == "number" then
return false, tostring(reason), ...
elseif type(reason) == "string" then
return false, reason, ...
else
error("Impossible")
end
end
function module.Simple<P..., R...>(
fn: (schema, P...) -> ((number | string | boolean)?, R...),
...: P...
): (boolean, string?, R...)
local tx = module.new()
return module.ParseResult(tx:exec(fn, ...))
end
If you change the second/third uses of P/R to something like P2/R2, it fixes the error. Additionally, I am unnable to change the “…: any — This really should be R… but it does not work at all” because it also results in an error:
Expected behavior
Types should not interfere with each other in different function declarations.