With the code below when using the __call metamethod instead of export.retry, all of the generics get infered to the self type of unknown, when it would be expected for the generics to still be generics.
local function retry<T..., A...>(max_attempts: number, callback: (T...) -> (A...), ...: T...): (boolean, A...)
local results = table.pack(pcall(callback, ...))
if not results[1] then
local attempts = 1
repeat
results = table.pack(pcall(callback, ...))
attempts += 1
until results[1] or attempts == max_attempts
end
return table.unpack(results) :: any
end
local function retry_call<T..., A...>(self: unknown, max_attempts: number, callback: (T...) -> (A...), ...: T...): (boolean, A...)
return retry(max_attempts, callback, ...)
end
local mt = {
__call = retry_call
}
mt.__index = mt
local tbl = {
retry = retry
}
-- first argument of setmetatable even if its given a table throws a type error saying its not a table
local export: typeof(setmetatable(tbl, mt)) = setmetatable(tbl :: any, mt)
-- No error, works as expected, with the generics being infered properly
local success, result = export.retry(10, function(bar: number)
return bar * 2
end, 10)
--[[
TypeError: Type '(number) -> number' could not be converted into
'(...unknown) -> (...unknown)'
caused by:
Type 'unknown' could not be converted into 'number'
--]]
local success, result = export(10, function(foo: number)
return foo + 1
end, 10)
The issue with the metamethod type gets fixed when the self type itself is a generic,
with the solver properly infering the functions generics
local function retry_call<S, T..., A...>(self: S, max_attempts: number, callback: (T...) -> (A...), ...: T...): (boolean, A...)
return retry(max_attempts, callback, ...)
end
With the code below when using the __call metamethod instead of export.retry, all of the generics get infered to the self type of unknown, when it would be expected for the generics to still be generics.
The issue with the metamethod type gets fixed when the self type itself is a generic, with the solver properly infering the functions generics