luau icon indicating copy to clipboard operation
luau copied to clipboard

Type error occurs when using templated methods during table iteration

Open GabeMillikan opened this issue 11 months ago • 1 comments

Reproduction

For example, in this code:

type Class = {
    method: <T>(Class, T) -> T
}

local objects: { Class } = {}
for _, object in objects do
    object:method(123) -- ERROR
end

The following error is raised on the object:method(123) line:

TypeError: Type 'Class' from 'example.lua' could not be converted into 'Class' from 'example.lua'
caused by:
  Property 'method' is not compatible.
Type
    '(Class, number) -> number'
could not be converted into
    '<T>(Class, T) -> T'; different number of generic type parameters

Impact

You don't even have to call the method in order to experience the issue. For example, your template method could be buried in a descendant class:

type Class = { method: <T>(Class, T) -> T }
type Parent = {
  child: Class,
  foo: (Parent) -> (),
}

local parents: { Parent } = {}
for _, parent in parents do
  parent:foo() -- 'Parent' could not be converted into 'Parent'
end

This, and the nonsense message, makes the error very frustrating.

Workaround

for _, object in objects do
    (object :: Class):method(123) -- no error
end

This makes the code look very silly, since object is already a Class. It is also somewhat challenging to come up with this workaround on your own, and it's likely that people are just casting object :: any and destroying type safety.


For some additional context, I've been complaining about this in the Roblox OSS Discord for a while.

GabeMillikan avatar Dec 18 '24 04:12 GabeMillikan

Same problem for a library here (https://github.com/alicesaidhi/skilift) Having to type cast it even outside of the library to stop the type errors is quite annyoing.

ghost avatar Mar 22 '25 13:03 ghost