-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeScriptToModel fails with type that contains a self reference #32
Comments
Running into this with Supabase generated types of the structure: type Database = {
public: {
Tables: {
foo: {
Row: {
bar: Database["public"]["Enums"]["Bar"];
};
};
};
Enums: {
Bar: "baz" | "quz";
};
};
}; |
So I did a decent amount of investigation here and it's a fairly challenging problem to solve. I took a bunch of stabs at modifying the generated code to make lazily evaluate with getters or closures with no success. I ended up trying to modify the This is still a great improvement over the previous code as it doesn't throw, but it's still not generating all of the final model's types correctly. I think the next steps are to keep a reference tree in the generator of all self-references and iterate over them continuously until the desired reference is available, while avoiding circular references. @sinclairzx81 Do you have any thoughts on this? I'm not even sure if this is the correct approach since this would require modifications to both the typebox and codegen libs. Seems wrong 😓 |
@florence-wolfe Hi, Unfortunately, there's no simple solution to this. With the exception of Type.Recursive, TypeBox self-referential types are generally not well supported with mapping types (like Index), and lazy types are generally considered to be out-of scope (as it primarily focuses on constructing immediate schematics). The only way to really generate something like the proposed Database type would be to hoist the interior index type into it's own variable. The following layout should be supported with current library transforms, but the complexity to hoist the type may be a bit too prohibitively complex for this code generator. import { Type } from '@sinclair/typebox'
// hoist the Bar out into it's own type
const ____Bar = Type.Union([
Type.Literal('baz'),
Type.Literal('bar')
])
const Database = Type.Object({
public: Type.Object({
Tables: Type.Object({
foo: Type.Object({
Row: Type.Object({
bar: ____Bar // js reference here
})
})
}),
Enums: Type.Object({
Bar: ____Bar // js reference here
})
})
}) There may be cases where the above may not work (specifically mutual recursive cases) but would be certainly be happy to review a PR if you wanted to try detect for self referential types. I would aim for the above layout as a possible starting point. Hope this helps! |
I'm working with TS files that contain references to types defined in the same interface. TypeScriptToModel seems to be using Recursive types for this scenario but fails when the nesting is more than one level deep.
Example:
TypeBox Workbench link
The text was updated successfully, but these errors were encountered: