trpc icon indicating copy to clipboard operation
trpc copied to clipboard

[v10] bug: TypeScript not willing to serialize the type of my client

Open anthonyshew opened this issue 3 years ago โ€ข 6 comments

Provide environment information

System: OS: macOS 12.5 CPU: (10) arm64 Apple M1 Pro Memory: 152.64 MB / 32.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node Yarn: 1.22.19 - ~/.nvm/versions/node/v16.16.0/bin/yarn npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm Browsers: Chrome: 104.0.5112.101 Safari: 15.6

Describe the bug

I am seeing an error in my editor saying: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. on my setupTRPC for my Next.js project.

This is coming after a migration from v9 to v10 where I was hoping to see this problem resolve. However, it seems to have moved from my root router to the setupTRPC.

This leads me to believe that the type annotation is getting too long for the TS interpreter in VSCode so it's punting the effort/complaining. However, I'll let the real TS genies figure it out. ๐Ÿ˜„

To reproduce

Providing a minimal reproduction might not be applicable here? This bug occurs because of lots of code, not little code. ๐Ÿ˜„

Rather, here is a link to my source code.

You'll find the TS error on this line.

Removing these two falsy declaration values from tsconfig will reveal the error!

Additional information

No response

๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Contributing

  • [ ] ๐Ÿ™‹โ€โ™‚๏ธ Yes, I'd be down to file a PR fixing this bug!

anthonyshew avatar Aug 28 '22 01:08 anthonyshew

Thanks for having the repo, helps a lot to have a repo to play with! Would you be able to add me as a contributor? Then I can play around with different things as soon as I get the time

KATT avatar Aug 28 '22 20:08 KATT

Thanks for creating this! It makes sense as our proxy types are huge to emit. But users shouldn't need to emit types for the client.

If you did need to emit types for the server: In your current setup, emitting types for the router would work fine since there's no error there. You'd be free to share/consume that in your client packages. And presumably, you'd never need to emit types for your Next app or any other tRPC client.

That being said, we should look into making all our types as small as possible.

sachinraja avatar Aug 28 '22 22:08 sachinraja

Also running into this issue but on the line where I'm constructing the reactQueryHooks:

import type { TrpcAppRouter } from "@avenueops/api";
import { createReactQueryHooks, TRPCClientError } from "@trpc/react";

// This line throws the exception
export const trpc = createReactQueryHooks<TrpcAppRouter>();

SamSokolin avatar Sep 07 '22 20:09 SamSokolin

Ended up finding an answer to this in the tRPC Discord. Looks like this is a v9 problem (which my project is still currently on). Will try upgrading to v10 as suggested and see if the issue goes away! Given that @anthonyshew is already on v10, looks like he may be having a separate issue.

CleanShot 2022-09-07 at 16 59 12@2x

SamSokolin avatar Sep 07 '22 21:09 SamSokolin

Note-to-self / @trpc/trpc-core. Potential actions

  • Easy: Add note that you need declaration: false in the docs
  • Hard: Revisit how we do the proxy API. Would have a bad impact on DX ๐Ÿ˜จ

KATT avatar Sep 08 '22 10:09 KATT

@sachinraja would you agree that we should close this as sort of out-of-scope or should we do some further actions?

KATT avatar Sep 21 '22 20:09 KATT

Agree that we can close as out of scope but we should definitely note this in the docs

sachinraja avatar Sep 21 '22 22:09 sachinraja

This issue has resurfaced for us even after upgrading to v10.0.0-proxy-alpha.74.

Type error: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.

         2 | import { createTRPCReact, TRPCClientError } from "@trpc/react";
         3 |
       > 4 | export const trpc = createTRPCReact<TrpcAppRouter>();
           |              ^
         5 |

Any recommendations on path forward? We are considering just splitting the routers but that isn't ideal. We only have about 20. cc @SamSokolin

amolpatel avatar Sep 22 '22 14:09 amolpatel

@amolpatel is declaration: false a solution for you?

KATT avatar Sep 22 '22 17:09 KATT

I played around a bit with this here and it doesn't look to bad already?

  • https://github.com/KATT/trpc-declaration
  • https://github.com/KATT/trpc-declaration/blob/next/build/utils/trpc.d.ts
  • https://github.com/KATT/trpc-declaration/blob/next/build/server/_app.d.ts

I notice that the Context is duplicated (the foo: "bar"-thing)... but unsure how we could unsure that wasn't the case ๐Ÿค”

KATT avatar Sep 22 '22 20:09 KATT

@amolpatel is declaration: false a solution for you?

In my case I could not disable the declarations since I needed to have composite on. Hmmm, not sure what else to do there ๐Ÿ˜–

PS: declaration: false does work but another project that references the tsconfig in question complains about the missing composite option which in turn requires declaration: true

IgnusG avatar Sep 24 '22 22:09 IgnusG

Is anyone able to create a reproduction of this issue? Would help to diagnose and potentially fixing it

KATT avatar Sep 25 '22 07:09 KATT

Hi, I am running into this issue when i try to export an "SDK" towards our application as a package in a monorepo. The proxy types fail using build, with like 4 routes with 10 procedures each (ouch...). I see that removing generation of declaration is deemed as a workaround, but i don't see how this would work considering we would like types for the consumers of the externally published SDK package.

While the above trpc-declaration repo doesn't "look too bad", as soon as we add some procedures using prisma and add prisma, session etc to the context (similar to create-t3-app examples), we soon end up with 21k+ lines of code in the types. That is with 4 routes as stated above, and as soon as i add a couple more procedures i end up with this error.

I am guessing i need to rethink something with my application, or how i export the external SDK-package. Any idea how to avoid this or to debug further? I tried creating a minimally reproducible repo but this seems to require quite a few components and could even be related to the internal company build-configs we use.

datagutt avatar Sep 27 '22 13:09 datagutt

Hey @KATT, I work on the same project as @amolpatel. Unfortunately, I don't think declaration: false is an option for us because it's required to use project references, which we rely on pretty heavily throughout our monorepo. We can reliably reproduce the issue but the project isn't open source. I'd be happy to hop on a Zoom with you and walk you through where we're running into it.

In the meantime, we ended up using a split link and two separate routers to unblock ourselves, like so: CleanShot 2022-09-27 at 14 19 27 Def a little janky b/c it requires us to use multiple tRPC clients throughout the frontend, but works for now!

cc: @sachinraja

SamSokolin avatar Sep 27 '22 18:09 SamSokolin

Looking into this now.

sachinraja avatar Oct 02 '22 15:10 sachinraja

So #2890 should help but here's an optimization that you can make:

// instead of this
export type AppRouter = typeof appRouter

// use this
type AppRouterType = typeof appRouter
export interface AppRouter extends AppRouterType {}

this forces TypeScript to emit the named AppRouter type for React instead of fully resolving the type again.

sachinraja avatar Oct 02 '22 16:10 sachinraja

#2890 cuts the declaration size of the server code in half. I'll do a release for that soon. But that, combined with the above comment, should fix this issue.

sachinraja avatar Oct 02 '22 17:10 sachinraja

Released in v10.0.0-proxy-beta.13, please test that and get back to us.

sachinraja avatar Oct 02 '22 17:10 sachinraja

Released in v10.0.0-proxy-beta.13, please test that and get back to us.

@sachinraja

I'm getting type errors in my client that are not present on 12, looks like bug related to this issue.

I'm using https://trpc.io/docs/v10/merging-routers#merging-with-child-routers

and on https://trpc.io/docs/v10/vanilla#initialize-a-trpc-client

getting

Type 'Router<RouterDef<{ user: { sub: string; email: string; user_metadata: { picture?: string | undefined; name?: string | undefined; }; } | undefined; }, DefaultErrorShape, {}, { ...; }>> & { ...; }' does not satisfy the constraint 'Router<any>'.
  The types returned by 'createCaller(...)' are incompatible between these types.ts(2344)
Screenshot 2022-10-03 at 17 02 11

noty-nick avatar Oct 03 '22 15:10 noty-nick

@sachinraja Thanks for the quick turnaround here! Will test w/ our project soon and lyk if we run into any issues. Just to clarify, the result of this is reducing the generated type size by a factor of 1/2? If so, does it perhaps make sense to document a recommended workaround when the issue resurfaces (via split links or otherwise)? Generally curious on your thoughts re: dealing w/ large routers in the future!

SamSokolin avatar Oct 03 '22 19:10 SamSokolin

@noty-nick I can't reproduce, could you share a repo?


@SamSokolin

Just to clarify, the result of this is reducing the generated type size by a factor of 1/2? If so, does it perhaps make sense to document a recommended workaround when the issue resurfaces (via split links or otherwise)?

Possibly, but ideally we'd deal with the issue if it resurfaces again. Split links are a good solution though, seems similar to #1226

sachinraja avatar Oct 04 '22 00:10 sachinraja

I'm trying to reproduce this in #2947 but to no avail. Feel free to jump in and modify the router I've created there (@datagutt @SamSokolin @anthonyshew @amolpatel).

KATT avatar Oct 09 '22 10:10 KATT

Looks like it's been squashed for me!

anthonyshew avatar Oct 12 '22 03:10 anthonyshew

Okay. This will be closed soon as we have an automated test that does this with 700 procedures.

Please reopen if you encounter these issues again.

KATT avatar Oct 12 '22 07:10 KATT