Coming from tRPC land I want to set up
Coming from tRPC land, I want to set up end-to-end typing with Convex. What is the suggested pattern for getting this done? For example, I have a function —
projects:create
— which has the following signature:
But, when I go to call useMutation("projects:"create")
on the React side of things, the return type is inferred as Promise<any>
whereas I'd like it to be Promise<Document<"projects">>
.
Thanks in advance!19 Replies
This should work with convex! I believe you just need to keep
npx convex dev
running in the background to make sure the generated type annotations stay up to date.Here's an example from my app:
(screenshot from vscode hovering over the mutation)

And I hovered over
m
That also works for me for simple return types (number, string, etc.). But not when I try and return a document (from the "projects" collection in my case). Is this expected?
That's unexpected! Sometimes I've found that I need to open the
_generated/api.d.ts
file in my editor (I use VSCode) to get it to pick up on the latest changes. I'm also curious if running TypeScript over your project directly catches type errors.No luck with either of those unfortunately.
I'm also using VSCode, using VSCode's TS version of 4.9.5, and am running convex in a NextJS app. I can try putting together a reproduction if there are no alternatives
@sp85 Do you have a schema.ts file?
Defining a Schema | Convex Developer Hub
End-to-end type safety requires typing your tables.
Yup!
What does
mutationWithSession
look like for you? I wonder if types are getting lost on the way via that middleware pattern.
I am trying to repro currently and can't. I made a function that returns a document
defined as such on the convex side:

I got
mutationWithSession
from https://github.com/get-convex/convex-helpers/blob/main/convex/sessions.ts . Not sure if that's the cause though, testing with a regular mutation with a document return type yields the same result.GitHub
convex-helpers/sessions.ts at main · get-convex/convex-helpers
A collection of useful code to complement the official packages. - convex-helpers/sessions.ts at main · get-convex/convex-helpers
If you can post the code would love to see it, or if you want to hop on a call we could look together
A call would be preferable, thanks
send you a DM with a link
Wrapping this up: there's an interesting issue with TypeScript as configured in the default Next.js template and perhaps any use of the
tsconfig.json
baseUrl
property.
With a "baseUrl": "."
, TypeScript interprets import * as s from "foo"
first as an import of ./foo.ts
, then only if that file doesn't exist as an import of the npm package foo
.
For convex this means convex/schema.ts
and convex/schema
package export being confused. Changing the name of the convex/
directory (which also needs to be updated in convex.json
) works around this for now.
sleuthed by @sshaderOh wow. Great find.
and big props to @sp85 for figuring out that baseUrl made the difference, that's what got us close
Filed a Next.js bug https://github.com/vercel/next.js/issues/46288
GitHub
baseUrl in create-next-app causes local files to shadow npm package...
Verify canary release I verified that the issue exists in the latest Next.js canary release Provide environment information tomb@Thomass-MacBook-Pro-2 abcef % npx --no-install next info Operating S...
this may be a TypeScript issue, but going to read more about how baseUrl is supposed to work before claiming that