create-t3-turbo
create-t3-turbo copied to clipboard
bug: go to definition is not working
Provide environment information
System: OS: macOS 14.5 CPU: (10) arm64 Apple M1 Pro Memory: 57.50 MB / 32.00 GB Shell: 5.9 - /bin/zsh
Binaries: Node: 20.11.1 - ~/.nodenv/versions/20.11.1/bin/node Yarn: 1.22.19 - /opt/homebrew/bin/yarn npm: 10.2.4 - ~/.nodenv/versions/20.11.1/bin/npm pnpm: 9.6.0 - /opt/homebrew/bin/pnpm bun: 1.0.0 - ~/.bun/bin/bun Watchman: 2024.05.06.00 - /opt/homebrew/bin/watchman
Describe the bug
I cloned the repository, trying to navigate through code. I am unable to go to definition (as well as see usages) of procedure in both VSCode and RubyMine (IntelliJ). I have another project with simple Next.js tRPC without monorepo and it's working fine there. Any ideas?
https://github.com/user-attachments/assets/352ce458-9dca-418c-b134-107d48a1f81e
https://github.com/user-attachments/assets/73f75a82-4a1a-4bf4-92cd-5af17df6c3ea
Link to reproduction
none, just clone template repo
To reproduce
Clone repo, try to navigate to definition
You need to run a build first so the declaration files are emitted.
We use declaration files to keep the tsc performance up as the project scales, a downside with that is that you lose "live types"
Thank you for the response, but I already run pnpm run build as you can see in vscode video above.
Also, in RubyMine, it points to to dist directory (as video shows above)
i see - do you have the workspace typescript version configured? that can sometimes mess with stuff
Yes, I use workspace version 5.5.4. "Live types" work fine even without running the build. I manually edited post.all procedure to return different object and typescript automatically infers that. So that works fine.
But Go to definition does not work. Do you have different behaviour please?
In adition, if I use typescript workspace version in RubyMine, api is typed as any. If I use bundled version 5.2.2, I get the behaviour from the video above
Same issue. It goes to definition only when this is set
"types": "./src/index.ts"
instead of
"types": "./dist/index.d.ts".
with .d.ts it goes here instead of actual definition
export const appRouter = createTRPCRouter({
test: testRouter
});
Same issue. It goes to definition only when this is set
"types": "./src/index.ts"
instead of
"types": "./dist/index.d.ts".
with .d.ts it goes here instead of actual definition
export const appRouter = createTRPCRouter({ test: testRouter });
Yes, I also edited it exactly as you did and now it works. Not sure if there are any consequences
Same issue. It goes to definition only when this is set
"types": "./src/index.ts"
instead of
"types": "./dist/index.d.ts".
with .d.ts it goes here instead of actual definition
export const appRouter = createTRPCRouter({ test: testRouter });Yes, I also edited it exactly as you did and now it works. Not sure if there are any consequences
vscode performance
Hm. I suspect this is a bug in TypeScript's declarationMap
@juliusmarminge, does t3-turbo's jump to definition work for you? I get this behavior as well:
https://github.com/user-attachments/assets/6b1716af-b475-4526-9db9-5534d6f04b70
Unsure if there's anything we can do here from tRPC's standpoint
Hm. I suspect this is a bug in TypeScript's
declarationMap@juliusmarminge, does t3-turbo's jump to definition work for you? I get this behavior as well:
https://github.com/user-attachments/assets/6b1716af-b475-4526-9db9-5534d6f04b70
Unsure if there's anything we can do here from tRPC's standpoint
I'll take a look on Monday but I know at our work repo I have jump to definition working with declaration emission
This will be fixed by https://github.com/microsoft/TypeScript/pull/60005
This issue seems pretty low on the ts team's priorities right now, especially as they are porting. I tested the latest tsgo lsp, and it will at least take you to the type declaration for the actual implementation, so there is hope this will be resolved in the natural process of porting lsp functionality.
In the interim, i whipped together this ts plugin(with some help from claude-code): trpc-navigation-plugin
It sidesteps the inference all together and uses some simple heuristics to identify what is your main router, when you are using it, then works through the ast from there to locate the proper "goto" file and position.
Also on npm as trpc-navigation-plugin. It has fully resolved all these issues in our monorepo, which is based structurally on the t3-turbo repo. Hopefully this can help someone else!
@juliusmarminge appreciate all your work on this repo, would love any feedback.
In the interim, i whipped together this ts plugin(with some help from claude-code): trpc-navigation-plugin
@ebg1223 I tested your plugin, thanks for the work!
I had to adjust my setup a bit to make it work tho. The plugin expects the Trpc router to be either in the form of t.router or a function called router.
I am using the same setup as the t3-turbo template where I define router as plain objects and type it with satisfies TRPCRouterRecord.
export const postRouter = {
all: publicProcedure.query(({ ctx }) => {
return ctx.db.query.Post.findMany({
orderBy: desc(Post.id),
limit: 10,
});
}),
} satisfies TRPCRouterRecord;
- I needed to define them like this to prevent some "max depth" issue with typescript.
Since this router definitions didnt work with trpc-navigation-plugin, I had to define a helper function that basically types the router objects and fulfills the "router" name requirement for the plugin.
/**
* A dummy identity function to trick the trpc-navigation-plugin into
* recognizing routers defined as plain objects.
*/
export const router = <T extends TRPCRouterRecord>(t: T) => t;
...
export const postRouter = router({
all: publicProcedure.query(({ ctx }) => {
return ctx.db.query.Post.findMany({
orderBy: desc(Post.id),
limit: 10,
});
}),
});
I also figured that the plugin is not working with the new standard Trpc Tanstack Query integration, which doesnt use the Trpc "useQuery" wrapper anymore. The plugin does search for a ".useQuery" function, so the following usage would not work:
const greetingQuery = useQuery(trpc.greeting.queryOptions({ name: 'Jerry' }));
To make it work, I had to fork the plugin and add queryOptions to the regex. @ebg1223 I am going to open a pull request on your repo.
Having to use a plugin for this is a pity but at least now I can work with type declaration files, which makes intellisense way faster in a monorepo and still get direct go to navigation.
Thank you so much @prometx11 for the support and contribution. I merged a day or so ago. Since then, I have been working on some improvements.
It no longer does any pre-resolution or caching. It can infer completely dynamically, with a little less config.
See the latest version(0.3.0): https://github.com/ebg1223/trpc-navigation-plugin
I believe if configured, it should work with both patterns, as well as objects that use satisfies, without any wrappers or additional work.
There is also this example repo: https://github.com/ebg1223/trpc-plugin-demo It is the latest t3-turbo, with just the plugin configured and enabled.