zod
zod copied to clipboard
Q: why discriminatedUnion of one element is not possible
According to discriminatedUnion
type definition, it accepts a list of at least two elements.
My question is why is this implemented like this?
Question arose for the reason that I have a real use case where I have a factory function that would return parsers for n>=1 string literals i.e.
const makeApiIdParser = (literals: NonEmptyArray<string>) => z.preprocess(
(uuid) => {
if (typeof uuid !== 'string') throw new Error('must be a string');
const [type, id] = uuid.split(SEPARATOR);
return { type, id };
},
z.discriminatedUnion('type', literals.map((type) => z.object({
type: z.literal(type),
id: z.string(),
})))
);
This function would generate parsers for such strings as user::27f4ee03-e79e-470c-8d4e-fa28e8ac6089
but also a separate parsers for such strings as blog::7fe494ab-a349-4896-87f2-24e2024d2cce
or collective::69e23e02-546b-4c30-a532-b3f45e8498f8
I could get by with if/else checking for my literals length, but it goes against normal intuition and would be akin to doing
const map = <T, R>(a: T[], f: (t: T) => R): R[] => {
if (!a.length) return a;
return a.map(f);
}
I hope this is a clear enough parallel to why I see the definition of discriminatedUnion
as a bit weird.
There must be some technical restriction I don't see or some logical aspect I fail to recognize.
Could someone please help me to understand the reason for this implementation of discriminatedUnion
?