convex-helpers migrations code failing tsc
I cannot get rid of tsc failures coming out of the migration helper. I never have node modules show up in type checking, and I do have
compilerOptions.skipLibCheck
set to true
on both of my tsconfigs.
Convex's own typecheck doesn't fail, my root project tsc does.
I've confirmed that I'm only import from convex-helpers
within the convex/
directory.
Any thoughts?
(cc/ @ian)
43 Replies
Thanks I’ll take a look. This is on latest version of convex & helpers ya?
Yep, convex@1.13.0, convex-helpers@0.1.45
I have a few other things I need to look into first - does changing your tsconfig to skip lib checks fix it for now?
It doesn't, that's the issue
I'll try nuking node_modules and see if that helps for some reason
Didn't work
Given that you're exporting TypeScript files, I guess I would expect those to get checked if I'm importing, even with skipLibCheck on.
Root tsconfig:
Convex tsconfig:
Adding
moduleResolution: "Bundler"
to my root config seems to have fixed it
I don't know how Expo/react native feels about that, but so far so good
Calling this solved for nowinteresting. I bet it's
noUncheckedIndexedAccess
that's causing at least one of those. I can add some stricter checks to helpers to try and catch more of these. Thanks for flaggingGitHub
Stricter tsconfig by ianmacartney · Pull Request #166 · get-convex/...
Improving the tsconfig strictness so we don't cause type issues for developers importing this code
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute ...
Quick!
Not sure if it's related but I experienced type errors caused by
.js
file references in convex-helpers
.
I'm using import { zid } from 'convex-helpers/server/zod';
in my @packages/shared
I use zid()
Convex helper in my Zod schema definitions in my shared package, but when the @apps/frontend
tried to pull in and use my Zod schema defined in @packages/shared
is didn't work because of the .js
references in
Example occurrence of the .js
reference:
I'm using ESM, "type": "module"
in my @apps/frontend
. To solve this, I needed to copy the zid
helper from convex-helpers
over to my @packages/shared
package and rework the imports to remove these .js
references and it works fine.
Is there a better way to solve this issue?What is your
moduleResolution
setting in your tsconfig? bundler
doesn't require the file extensions, nodenext
I believe does which is why I put the extensions in there.
https://www.typescriptlang.org/docs/handbook/modules/reference.html#relative-file-path-resolution implies that every moduleResolution setting should support the relative import with .js
, but maybe something else is messing it up..I'm using
bundler
as my moduleResolution in both @packages/shared
and @apps/frontend
Would you mind sharing the rest of your tsconfig so I can try to repro? Or do you have a repro you can share?
I'm just trying to reproduce the error again to see the specific issue.
Ah yes, now I recall the issue. It was with my react native app (expo v51). This is the specific error:
Here is my
tsconfig.json
for the expo app:
So it's "moduleResolution": "node"
, not bundler
sorry.
Btw, switching "allowJs"
to true
doesn't seem to help..Does changing moduleResolution here to bundler or nodenext help?
I tried both bundler and nodenext, but neither fix the issue.

When I try to remove the
.js
I get an error for my own moduleResolution, so there must be some way..
It it possible for
convex-helpers
to use bundler
as the moduleResolution
given this is what the main convex
package now uses? I'm using bundler
in my @packages/shared
with these helper functions copied over and everything works ok (with the .js
removed from the imports).I've reproduced it and it seems to be the expo bundler. I've removed all
.js
imports in the package in favor of absolute ones in an alpha build: 0.1.46-alpha.0
you can use. I'm having some trouble getting tests to like the approach, so I may have to go a different direction with the non-alpha release, but hopefully that works for you
@adam convex-helpers@0.1.46
goes with the approach you suggested: changing them all to node-style imports and using bundler
module resolution. I might go back to nodenext but I'll make sure expo is happy with it.
I validated it against our monorepo template (which I updated to newest expo / turbo while I was there)
@erquhart ^^ also since you I believe have been looking at convex-helpers with Expo recently?I've just tested
0.1.46-alpha.1
with my bun monorepo setup and it now looks to be working well. Thanks very much - nice work.
Note that I needed to update my Expo tsconfig.json
to use "moduleResolution": "bundler"
and not "moduleResolution": "node"
which I believe is the default.
convex-helpers@0.1.46
is also working well.good to know, and glad to hear it - I wonder if the alpha.0 version didn't need the resolution change 🤔.
It's pretty unfortunate that Expo's bundler seems incompatible with nodenext typescript packages - unless I can find another way to tell it to start looking in
dist
. it ignores the exports
directive unless you toggle an unstable option (which then broke another package's bundling for my app). Maybe it's worth a patch that strips the .js
before looking for other extensions.I'll try the alpha 0 in a bit
@ian alpha 0 does fix my original issue without requiring a change to
moduleResolution
actually... now it's not having the issue at all anymore, even on latest 🤦♂️
What happened so far:
- I posted this issue, and fixed by changing moduleResolution of root tsconfig to bundler
- at some point after that, for unrelated reasons, I deleted node_modules entirely and reinstalled everything
- today, I went to check if alpha 0 addressed my original issue without a module resolution change
- before doing anything, I removed the module resolution change to make sure tsc still failed, which it did
- updated to alpha.0 - no failure
- updated to alphal.1 - no failure
- reverted to 0.1.46 (latest) - no failure
- uninstalled and reinstalled convex-helpers - no failure
🤷♂️Latest includes the alpha changes. I released it last night.
I would expect it not to work on 1. 45.
0.1.46
has a bad behavior where vitest expects the nodenext-style relative imports - so any project using vitest and convex-helpers would fail.
I've cut 0.1.47-alpha.2
that should support everything - relative imports, node resolution, nodenext, bundler, Expo, etc.
I'm going to cut 0.1.47
soon unless I hear it's causing either of you issues @erquhart @adamtrying the alpha now
looks to be working for me, expo only, no vite
0.1.47
is working well for me at runtime. I've tested using expo, vite and vitest (v2). I am however getting tsc errors which seem to be related to the validators change. I'm still on convex@1.12.2
due to outstanding optional types bug in convex@1.13.0
. I'll revert back to 0.1.43
for now.which types bugs are you blocked on in
convex@1.13.0
?I believe that was also fixed in
0.1.46
- can you try with 0.1.47
and convex 1.13
? Sorry I didn't follow up in that thread - Sarah fixed that along with two other issues in https://github.com/get-convex/convex-helpers/pull/167GitHub
Fix type issues from npm 1.13 by sshader · Pull Request #167 · get-...
Fixes three issues:
myCustomFunciton({ handler: (ctx, args: { foo: string } => ... }) now compiles
zodToConvex(z.object({ foo: z.number().optional() })) now yields { foo?: number | undefined } ...
Ok great. When I try to update:
convex 1.12.2 => 1.13.0
convex-helpers 0.1.43 => 0.1.47
convex seems to get stuck in an endless loop when running
npx convex dev

Do you have another
npx convex dev
process running somewhere by chance?I suspected that too but it doesn’t seem so. Also, when I undo the change then start up convex again everything works fine (no looping).
Huh! Could you try
npx convex dev --verbose
@adamthe mac file watcher also isn't the best piece of technology - I can't remember what's fixed it before when I saw this, whether it was a machine restart, finder restart, VSCode restart, etc.
I successfully got it upgraded to 1.13.0/0.1.47 after a restart of my macbook. Thanks @ballingt @ian
Just a note: I'm now seeing something like the original issue here after migrating to Convex auth, and it's specifically with files that import from the auth lib. I've changed
"moduleResolution"
to "Bundler"
in the root of my project to fix, but as before, ideally this wouldn't be necessary, as I'm not certain it's a welcome override for Expo.Something like the original issue being type errors about the unchecked index access? Can you paste the updated error?
Good point, these weren't errors from node_modules, so it's different. It's almost like
npx tsc
at root isn't respecting the convex directory tsconfig, but the vscode editor is. So the cli has errors but the editor doesn't. But this hasn't been an issue before, and it's all to do with code from the auth library (says it can't find the module). I can't dig into it anymore though, changing module resolution is working 🤷♂️ will update if that changes.
Thanks for checking in 👍you're using RN / Expo, so metro bundler? I believe that only works with node module resolution, and the convex auth package currently doesn't seem to have non-react entrypoints for node - something we can improve.
Metro hasn't complained yet. But I also haven't attempted a production build since migrating. Local dev bundling is working though.
But yeah that might fix it. I still don't understand why vscode editor had no type issues, but cli did. Using terminal in vscode and both using the same Typescript version. Might just be a setup issue.
re vscode respecting convex/tsconfig.json but not tsc, that's always been the behavior; the convex tsconfig.json is only used in editors and when Convex bundles, not when the app compiles
Interesting, maybe I should run two separate checks then
You can run the convex check with
npx convex typecheck
, it runs on dev automatically
and the main app one with something like tsc --noEmit
depending on your TypeScript setupOh nice didn't know about the convex command. I'll probably have to exclude the convex directory from my root config for the app check.
Actually that doesn't work because I import from convex all over the place. I don't think there's a current workaround that doesn't involve setting moduleResolution to bundler. I've always run with noEmit set to true via config.
makes sense, we'll add these somehow; Ian has written some scripts to generate these a few different ways
@erquhart if it's easy, I'd love to hear if
fixes for you