[v4] Type portability issues with `z.iso` and `z.coerce` (and possibly others)
Hello!
v4 looks great!👌 I found a few type portability issues during the migration.
Errors
After replacing z.string().datetime() with z.iso.datetime() I got a lot of errors like this in a monorepo:
error TS2742: The inferred type of 'iso' cannot be named without a reference to '../node_modules/zod/dist/types/v4/classic/iso.js'. This is likely not portable. A type annotation is necessary.
error TS2742: The inferred type of 'coerce' cannot be named without a reference to '../node_modules/zod/dist/types/v4/classic/coerce.js'. This is likely not portable. A type annotation is necessary.
I managed to transpile a package with oxc that had these errors but the generated type declarations there are also wrong:
import * as zod_v40 from "zod/v4";
import z$1, { z } from "zod/v4";
import * as zod_v4_core697 from "zod/v4/core";
import * as node_modules_zod_dist_types_v4_classic_iso43 from "node_modules/zod/dist/types/v4/classic/iso";
// ^ Cannot find module 'node_modules/zod/dist/types/v4/classic/iso' or its corresponding type declarations.ts(2307)
Reproduction
You can find a minimal reproduction here:
Workaround
Use the deprecated z.string().datetime() etc. until the issue is resolved.
Or add references to the problematic types to every file where the error occurs.
import type { z } from "zod/v4";
type SolveIsoDateTimePortabilityIssue = z.iso.ZodISODateTime;
type SolveCoercedNumberPortabilityIssue = z.coerce.ZodCoercedNumber;
// etc..
I had similar issues when using .catch(), temporarily using preprocess now.
Should be fixed in 3.25.41. @zsilbi give it a shot a report back if it isn't fixed.
@n3oney I couldn't replicate with .catch(). Seems like a different issue. I can look into it but I'll need a repro. Perhaps you can use the repro from @zsilbi as a starting point: https://github.com/zsilbi/zod4-type-repro
It seems to me that there is a similar issue with .extend(), see here.
import { z } from "zod/v4";
export const Foo = z.looseObject({
a: z.string(),
});
export const Bar = Foo.extend(z.looseObject({
b: z.string()
}));
❯ tsc -b
src/schema.ts:7:14 - error TS2742: The inferred type of 'Bar' cannot be named without a reference to '../node_modules/zod/dist/types/v4/core/standard-schema.js'. This is likely not portable. A type annotation is necessary.
7 export const Bar = Foo.extend(z.looseObject({
~~~
Found 1 error.
I see this is fixed now but I found a simple workaround. I just needed to have an import statement such as : import { z } from "zod/v4"; in the file, even though I'm not using z directly.