Open JacobWeisenburger opened 9 months ago
I also faced this problem. And i think it is a good idea add additional field for invalid_intersection_types
code with problematic field path.
For example, for the code below, the problematic field will be property.nested1
(because of mergeValues function behavior)
const schema = z
.strictObject({
property: z
.strictObject({
nested1: z.function(),
nested2: z.number()
})
.optional()
})
.and(z.custom((value) => !(value instanceof RegExp)));
const result = schema.safeParse({
property: {
nested1: () => {},
nested2: 1000
}
});
// Current error
{
code: 'invalid_intersection_types',
path: [],
message: 'Intersection results could not be merged'
}
// Expected error
{
code: 'invalid_intersection_types',
path: [],
problematicFieldPath: ['property', 'nested1']
message: 'Intersection results could not be merged'
}
But I don't know how to view this change from a semver point of view: breaking or not. Maybe someone can help me decide on this?
I'm also facing the same issue. As of now, we have no clue what exactly caused this error.
Below is the usage of intersection, which caused this error.
import { components as crmComponents } from '@generated/crm-service-types';
import { z } from 'zod';
import { PERSON_TYPES } from '@/constants/filter';
import { mandatoryMessage } from '@/types/common';
import { asOptionalField, requiredWithRefine } from '@/utils/validations';
export type OpportunityStatus = crmComponents['schemas']['OpportunityStatus'];
export const OpportunityStatusList: OpportunityStatus[] = [
'Interest',
'Quotation',
'CustomerDecision',
'Agreement',
'ClosedWon',
'ClosedLost',
];
export enum OpportunityStatusEnum {
Interest = 'Interest',
Quotation = 'Quotation',
CustomerDecision = 'Customer decision',
Agreement = 'Agreement',
ClosedWon = 'Closed won',
ClosedLost = 'Closed lost',
}
export enum OPPORTUNITY_STATUS {
INTEREST = 'Interest',
QUOTATION = 'Quotation',
CUSTOMERDECISION = 'CustomerDecision',
AGREEMENT = 'Agreement',
CLOSEDLOST = 'ClosedLost',
CLOSEDWON = 'ClosedWon',
}
const commonCreateEditOpportunityCheck = {
name: z.string(),
status: z.enum(
[
OPPORTUNITY_STATUS.INTEREST,
OPPORTUNITY_STATUS.QUOTATION,
OPPORTUNITY_STATUS.CUSTOMERDECISION,
OPPORTUNITY_STATUS.AGREEMENT,
OPPORTUNITY_STATUS.CLOSEDLOST,
OPPORTUNITY_STATUS.CLOSEDWON,
],
{
required_error: mandatoryMessage,
}
),
leasingCompany: asOptionalField(
z.object({
id: z.string(),
name: z.string(),
})
),
dealer: asOptionalField(
z.object({
dealerId: z.string(),
dealerName: z.string(),
})
),
salespersons: z
.array(
z.object({
id: z.number(),
firstName: z.string(),
lastName: z.string(),
email: z.string(),
loginId: z.string(),
})
)
.optional(),
additionalComments: asOptionalField(z.string()),
};
const personTypeValidation = z
.object({
type: z
.enum([PERSON_TYPES.BUSINESS, PERSON_TYPES.PRIVATE], {
required_error: mandatoryMessage,
})
.optional(),
organisation: asOptionalField(
z.object({
id: asOptionalField(z.string()),
name: asOptionalField(z.string()),
})
),
})
.refine(
(data) => !(data.type === PERSON_TYPES.BUSINESS && !data.organisation?.id),
{
path: ['organisation'],
message: 'Organisation is required for Business Customers',
}
);
export const EditOpportunityValidation = z.intersection(
z
.object({
...commonCreateEditOpportunityCheck,
newCloseDate: z.unknown().optional(),
customer: z
.object({
id: z.string(),
firstName: z.string().nullable(),
lastName: z.string(),
})
.optional(),
})
.passthrough(),
personTypeValidation
);
export const AddOpportunityValidation = z.intersection(
z
.object({
...commonCreateEditOpportunityCheck,
newCloseDate: requiredWithRefine(
z.any({ required_error: mandatoryMessage })
),
customer: z.object({
id: z.string(),
firstName: z.string().nullable(),
lastName: z.string(),
type: z.string(),
}),
})
.passthrough(),
personTypeValidation
);
I found I was getting this error when I was intersecting a passThrough
schema with a schema with coercion.
e.g., the following works
const mySchema = z.intersection(
z.object({
type: z.string(),
}).passthrough(),
z.object({
metaData: z.object({
timestamp: z.string().datetime(),
}),
}),
);
but the following gets the invalid_intersection_types
error
const mySchema = z.intersection(
z.object({
type: z.string(),
}).passthrough(),
z.object({
metaData: z.object({
timestamp: z.coerce.date(),
}),
}),
);
This also has the gives the same error
const mySchema = z.intersection(
z.object({
type: z.string(),
}).passthrough(),
z.object({
metaData: z.object({
timestamp: z.string().datetime().transform(value => new Date(value)),
}),
}),
);
Discussed in https://github.com/colinhacks/zod/discussions/3194