The use of recursive type definitions fail if there are metatables involved, which prevents the declaration of class/object types with recursive generic definitions, even if the generics are identical.
Simple example:
type List<T> = {Value: T, Next: List<T>?, Prev: List<T>?};
-- the following works as expected
local x: List<number> = {Value = 0};
x.Next = {Value = 2}::List<number>;
if x.Next then x.Next.Next = {Value = 3}::List<number> end;
local mt={};
type ListClass<T> = setmetatable<{Value:T, Next:ListClass<T>?, Prev:ListClass<T>?},typeof(mt)>;
-- the following has arbitrary type errors
local x: ListClass<number> = setmetatable({Value=0},mt); -- Type Error: Recursive type being used with different parameters
print(x) -- *error-type*
print(x.Next) -- Next: any

Expected behavior
ListClass<T>
should properly develop into the following type:
{Value: T, Next: ListClass<T>?, Prev: ListClass<T>?, @metatable {}}
and should not be creating type errors, or in the case of trying to do workaround such as
type INTERNAL<T, U=ListClass<T>?> = {Value: T, Next: U, Prev: U};
type ListClass<T> = setmetatable<INTERNAL<T>,typeof(mt)>; -- or setmetatable<INTERNAL<T, ListClass<T>?>,typeof(mt)>;
it should not result in *blocked-xxxx*
and *error-type*
types, nor the INTERNAL
type leaking out of the metatable definition