Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

zod TypeError: Cannot read properties of undefined (reading 'extend')

I have a Vite library using Vitest and Zod. Given the following folder structure

.
├── src
│   ├── leading
│   │   ├── index.ts ( 2 )
│   │   └── leadingDataSourceConfigurationSchema.ts
│   ├── index.ts ( 1 )
│   └── dataSourceConfigurationSchema.ts
└── test
    └── my.spec.ts

I created a base schema for data sources

import { z } from 'zod';

const dataSourceConfigurationSchema = z.object({
    id: z.string().min(1)
}).strict();

export { dataSourceConfigurationSchema };

exported by the index.ts ( 1 )

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

export * from "./leading";
export { dataSourceConfigurationSchema } from "./dataSourceConfigurationSchema";

I also have a schema extending the one above

import { z } from 'zod';
import { dataSourceConfigurationSchema } from '..';

const leadingDataSourceConfigurationSchema = dataSourceConfigurationSchema.extend({
    entityTypeId: z.string().min(1),
}).strict();

export { leadingDataSourceConfigurationSchema };

the index.ts ( 2 ) only exports this schema

export { leadingDataSourceConfigurationSchema } from "./leadingDataSourceConfigurationSchema";

When creating a test file like so

import { describe, it, expect } from 'vitest';
import { ZodError } from 'zod';
import { leadingDataSourceConfigurationSchema } from '../src';

describe('test', () => {
  it('fails.', () => {
    expect(() => leadingDataSourceConfigurationSchema.parse({})).toThrow(ZodError);
  });
});

the test fails with the following error message

TypeError: Cannot read properties of undefined (reading ‘extend’)

This problem might be related to

When replacing the import

import { dataSourceConfigurationSchema } from ‘..’;

with

import { dataSourceConfigurationSchema } from ‘../dataSourceConfigurationSchema’;

the test passes. So it seems the project is struggling with circular dependencies?

Do sub directories have to import files directly or can I fix this problem with a different approach?

>Solution :

Yes, you have a circular dependency, and due to the import order dataSourceConfigurationSchema will not yet be initialised when leadingDataSourceConfigurationSchema is intialised. This is not an issue of zod or vite (although with a proper ES6 module implementation, you’d get a TDZ error instead of a reference error from accessing a method on undefined).

As you saw, you can fix this by importing dataSourceConfigurationSchema directly from ../dataSourceConfigurationSchema.ts and not from ../index.ts, the module that imports leadingDataSourceConfigurationSchema.ts itself.

Another solution would be to change the order of imports in src/index.ts to

export { dataSourceConfigurationSchema } from "./dataSourceConfigurationSchema";
export * from "./leading";

but this is really fragile, so I wouldn’t recommend it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading