jgoux
jgoux16mo ago

Am I the only one struggling with pnpm + TypeScript monorepo + trpc?

Hello all, When using pnpm in a TypeScript monorepo without node-linker, I hit those errors:
web/src/lib/trpc.tsx:7:14 - error TS2742: The inferred type of 'trpc' cannot be named without a reference to '../../../api/node_modules/@snaplet/sdk/src'. This is likely not portable. A type annotation is necessary.

7 export const trpc = createReactQueryHooks<WebRouter>()
web/src/lib/trpc.tsx:7:14 - error TS2742: The inferred type of 'trpc' cannot be named without a reference to '../../../api/node_modules/@snaplet/sdk/src'. This is likely not portable. A type annotation is necessary.

7 export const trpc = createReactQueryHooks<WebRouter>()
Types sharing between packages when using pnpm + TypeScript is quite broken, and I'm not sure what's the best move to solve it. Ideally I shouldn't have to alter my compilerOptions.paths, or install extra deps in the root. 😅 I opened a discussion about it here if you want to participate: https://github.com/orgs/pnpm/discussions/6367
12 Replies
jgoux
jgoux16mo ago
I can solve this one 👆 (type sharing between internal packages) by altering the paths of the package exporting the types, I have to make it point to the other package's real location:
"@snaplet/sdk": ["../packages/sdk"],
"@snaplet/sdk": ["../packages/sdk"],
but that's just a hack and I hate it 😂 I ended not touching the paths and installed my @snaplet/sdk package at the root using "@snaplet/sdk": "link:packages/sdk", but I still have to manually delete the local symlink created for it in the dependant package 🤔
Ahmed Elsakaan
Ahmed Elsakaan16mo ago
actually i ran through this problem before you can do export type {} from '@snaplet/sdk'; in the index file of the trpc package no clue why it works but it does
Nick
Nick16mo ago
This isn’t really a hack, it’s the right solution. Depending on your repo setup you could also install the API into the Client. I’d like us to provide a decent guide on this stuff though as it’s a common confusion
jgoux
jgoux16mo ago
the api is installed into the client, that's why I call it a hack To me, even in a monorepo, you should not use paths to look outside of your package boundaries I actually "solved" the issue without touching the paths I needed to use pnpm's public hoisting so trpc gets installed at the root of the monorepo and satisfies TS weird resolution with symlink (which is the root cause of the error) I opened a discussion about it on pnpm's repo https://github.com/orgs/pnpm/discussions/6367
Nick
Nick16mo ago
Well yes the problem is that the client can’t resolve the tRPC types, by hoisting or installing those into your client it makes them available
Ahmed Elsakaan
Ahmed Elsakaan16mo ago
did you try this?
jgoux
jgoux16mo ago
yes it was also suggested in the issues I linked in the discussion, it didn't work in my case
Nick
Nick16mo ago
I did say depending on your setup though, there are some extra bits to do. Thing is typescript != node, and they both have some different bits they expect to see. Some package.json tweaks to the types key may also fix this It’s normal to add a path or project reference so that type resolution can work between monorepo packages
jgoux
jgoux16mo ago
I'd say the project references are meant to solve this, not paths (I use project references!)
Nick
Nick16mo ago
I’d love for us to write up some best practices around this, it’s hard to debug and answer from afar, and a big element of a tRPC project working right
jgoux
jgoux16mo ago
If you do, please ping me on GitHub I'd love to contribute 🙂
DiamondDragon
DiamondDragon12mo ago
i seem to have run into this as well. using drizzle and neon here, which is in another package being imported into packages/trpc. but removing the neon package and reinstalling at the root seems to fix
No description