Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated imports fail when running in node and using type: "module" in package.json #259

Open
t-animal opened this issue Aug 5, 2024 · 6 comments
Labels
enhancement New feature or request import related This issue is related to import handling

Comments

@t-animal
Copy link

t-animal commented Aug 5, 2024

Bug description

ts-to-zod does not include the filename in such a scenario, making it incompatible with "module"-packages running in node.

When running in node (i.e. not targeting a bundler/webbrowser), the typescript "module"-property must be set to "node16" or "nodenext". When using type:"module" in package.json, this means that imports have to include the ".js" suffix.

A minimal example would be:

//package.json
{
  "name": "test-modules",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {
    "ts-to-zod": "^3.10.0",
    "typescript": "^5.5.4",
    "zod": "^3.23.8"
  }
}


//tsconfig.json
{
  "compilerOptions": {
    "lib": ["ES2020"],
    "module": "NodeNext",
    "moduleResolution": "NodeNext"
  }
}


//ts-to-zod.config.cjs
module.exports = [
  { name: "b", input: "b.ts", output: "b.zod.ts" },
  { name: "a", input: "a.ts", output: "a.zod.ts" },
];


//a.ts
import { B } from "./b"; // This should be `import {B} from "./b.js";`

export type A = B | "a";


//b.ts
export type B = "b";

Running tsc gives the following error:

npx tsc
a.ts:3:19 - error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './b.js'?

1 import { B } from "./b"; // This should be `import {B} from "./b.js";`
                    ~~~~~


Found 1 error in a.ts:3

Our current solution is to fix the imports using sed in our build-script:

"build": "node ts-to-zod.config.cjs; npm run patch-zod-import; tsc",
"patch-zod-import": "sed -i 's/\\(^import [^\"]*\"\\.\\/[^\"]*\\).zod\";/\\1.zod.js\";/' src/schemas/*.zod.ts",

Input

Multiple files containing types, referencing each other. E.g:

//a.ts
import { B } from "./b.js";

export type A = B | "a";

//b.ts
export type B = "b";

Expected output

a.zod.ts should be:

// Generated by ts-to-zod
import { z } from "zod";

import { bSchema } from "./b.zod.js";

export const aSchema = z.union([bSchema, z.literal("a")]);

Actual output

// Generated by ts-to-zod
import { z } from "zod";

import { bSchema } from "./b.zod";

export const aSchema = z.union([bSchema, z.literal("a")]);

Versions

  • "ts-to-zod": "^3.10.0",
  • "typescript": "^5.5.4",
@tvillaren tvillaren added bug Something isn't working enhancement New feature or request and removed bug Something isn't working labels Aug 12, 2024
@tvillaren tvillaren added the import related This issue is related to import handling label Aug 26, 2024
@ydennisy
Copy link

ydennisy commented Sep 6, 2024

Hi @tvillaren do you have an ETA for a fix for this?

@tvillaren
Copy link
Collaborator

Hello,

Not really. I you have a solution in mind, please feel free to open a PR! 🙏
Thanks!

@t-animal
Copy link
Author

t-animal commented Sep 9, 2024

Fwiw, I saw that detection for this setting is already in the codebase, somewhere. I can't work on this atm, though....

@hongkongkiwi
Copy link

Be great to get a simple fix for this, because it makes it actually totally unusuable in Deno in certain situations (when importing other files, it MUST have the extension, you can't just import it without). This causes issues when you have multiple files relying on another.

I did have a sed workaround, but that only works in certain situations.

@hongkongkiwi
Copy link

To elaborate, this will fail in the validation step in certain cases, specifically for me it's when using an enum as zod wants to infer back to the original enum, but cannot and so ts-to-zod fails in the validation step and never generates the code (so we can't use sed).

@t-animal
Copy link
Author

For future reference: The code for detecting if the project has type: "module" is already here and I think the fix could be applied here, when actually writing the import to the output string or probably rather here, when creating the import node

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request import related This issue is related to import handling
Projects
None yet
Development

No branches or pull requests

4 participants