TypeScript reference cycles (`ts(7022)` errors)
Hello everyone,
I’m running into a TypeScript error that causes my table schemas to become type
any
. Here’s a simplified example illustrating the problem:
- There are two schemas, user
and team
.
- A user
may or may not have a team
(i.e., teamId
is optional).
- A team
may or may not have an owner
(i.e., ownerId
is optional).
- A team
may have many users
.
user.schema.ts
:
team.schema.ts
:
With this setup, TypeScript immediately reports these errors:
- Error on the schemas: '<schema>' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. ts(7022)
- Error on references: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ts(7024)
.
Question:
Is there any known workaround or recommended approach to avoid this circular reference / type inferred as any
issue and still keep references and relations in Drizzle?12 Replies
helper.ts
:
It didn't fit into the limit of the topic so I leave it as a commentDid you update your drizzle.config to handle multiple schema files?
What do you mean? I don't have any issues with the config. The issues are in schemas and are related to TS 😦
Oh you the your extra comment wasn't the visible when I added my comment. Thought you might have messed up your files. Anyway, I can see it now.
I guess you this ref function you've created isn't working. First, can you explain why do you need it?
It looks like it's just you're just taking extra steps to create a reference to a column
Why is a normal one-many relation and foreign key reference not good enough basically?
You trying to dynamically set foreign key to nullable/not-nullable but I don't see why you need this ref function if both teamId is optional and ownerId is optional
I think you didn’t get the question. I provided you with minimal code to reproduce, it is just made up scenario to show the problem. And helper functions here are not the problem at all. They work just fine. Did you try to run the code solution you provided? It is the same thing and it does not resolve the issue I described. Thank you for trying to help, but you are looking at different things
Create a codesandbox or like a drizzle.run example
You're trying to add a DB level FK reference
.references(() => user/team.id
to both sides the relationship. Just add it to the many side?
Or maybe if you type callback in your ref function
I'm on my phone right now so I'm not going to fork the sandbox but
.ref((): AnyPGColumn => user.id)
How would reference owner of team without FK to the user? I mean, if you have any ideas of correct implementation please let me know
Yeah so relations is a high level abstraction that defines relationships in your application at the application level. So short answer is Drizzle is doing it for you and you don't need to use
.references(() => user/team.id
but that doesn't mean you can't.
So in this case the issue isn't that you're trying to add DB level FKs it's that TS can't infer the type of column in .ref(() => user.id)
so maybe (I can't try it atm) .ref((): AnyPGColumn => user.id)
resolves the type issue.
This is the Drizzle application level relationship. It's simple and it will work with or without adding foreign key to your table columns
Thanks for clarifying! I’m aware that I can define an application-level relation without specifying references, but I really want a DB-level foreign key to guard my data. Right now, I’m using an application-level relation without an actual FK as a temporary workaround.
I’ll definitely try out your
AnyPGColumn
suggestion, I haven’t used that before, and let you know if it resolves the type inference issue.
@TOSL I tried to use AnyPGColumn
in one of the schemas where circular reference occurs, and it solved the issue with TS. Thank you!No problem glad that worked.