Setting up tRPC without breaking Frontend's typechecking
Hello everyone,
I would like to better understand how I can setup my project correctly. Right now I'm using Fastify with tRPC. My frontend is a React Native app. Both live in a monorepo using yarn workspaces.
I'm exporting my tRPC types like this:
In the backend I'm exporting my
AppRouter:
And I'm importing it like this:
So while this instantly reflects any changes in the frontend, e.g. if I change a property of an input DTO, this breaks my typechecking. If I run tsc I'm getting errors from my backend code. The errors are primarily coming from - allegedly - missing properties related to my Drizzle schemas. Also I'm using path aliases in some backend files, which also produces an error when typechecking. I can potentially fix these by not using path aliases at all. If I run tsc in the backend everything is fine though, so I'm not sure if any of those errors (except the path aliases) make sense.
What are my options here? My setup feels flawed. How do I set this up correctly? I can see that I can potentially export a transpiled type file for my backend API, but I would need to combine this with a watcher task to reflect changes in the frontend immediately. When testing this approach it was lagging behind my current approach, but it allowed me to perform typechecks using tsc just fine.6 Replies
I found a lot of example projects which just straight up import from the backend without a monorepo setup ❓
If I run tsc I'm getting errors from my backend code.Does this mean that
AppRouter is broken?No, I think the issue is that my context was referencing the
FastifyInstance, thus including back-end code, which also included path aliases, which then in return breaks in the front-end as those path aliases are not known.
I was worried that just straight up importing the AppRouter from the back-end might end up with me accidentally shipping back-end code with my app, so I ended up implementing an additional build step for the AppRouter types which produces dist/trpc-types.d.ts. I lost the instant feedback from VSCode though (I have to wait for the watch task and the VSCode reload).@ConfusedCompiler Could you share a bit more info about how you achieved this? I ran into the same exact problem. If I use any server-sided logic which doesnt make sense on the client side (Open files etc.) The client gets broken since it tries to transpile that too
I'm not sure how this is not a more reoccurring error? It seems such a common problem, I'm doubting whether I'm doing something wrong
Yeah right? From inspecting a lot of example repositories I saw that many developers just make sure that they only import the type of the AppRouter (should be standard practice anyways) and that their back-end code has no gotchas which couldn't be transpiled in the front-end, e.g. no path aliases.
Since I, personally, feel like that it's a bit risky to trust arbitrary linting rules to make sure that I don't accidentally leak my entire back-end into my front-end, I changed my
package.json to:
And then I just have a watch task running in the background.
Downside: VSCode automatically and instantly picks up type changes even before saving the file. With this approach there's a noticeable delay between making a change to the back-end and getting an error in the front-end codeThanks for the reply! I'll see about implementing it like that in my own project.