Function to create a union of literal dynamically #2790
-
Currently, it does not seem to be possible to create a function that does union of literal, like: function unionOfLiterals<T extends string | number>(constants: readonly T[]): z.ZodUnion<[ZodTypeAny, ...ZodTypeAny[]]> {
const literals = constants.map((constant) => z.literal(constant)) as [z.ZodLiteral<T>, ...z.ZodLiteral<T>[]];
return z.union(literals);
}
const MY_CONSTANTS = ['a', 'b', 1] as const;
const unionType = createUnionType(MY_CONSTANTS); This code gives the following typing error:
And a call to this method returns a z.ZodUnion<[ZodTypeAny, ...ZodTypeAny[]]> object. Providing the constants directly is straightfoward: z.union([z.literal('a'), z.literal('b'), z.literal(1)]) If that was possible, it would enable several use cases for using solely zod for API input validation. Now I end up losing typing when doing that indirectly. Amazing library, by the way. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Is this what you are looking for? function unionOfLiterals<T extends string | number> ( constants: readonly T[] ) {
const literals = constants.map(
x => z.literal( x )
) as unknown as readonly [ z.ZodLiteral<T>, z.ZodLiteral<T>, ...z.ZodLiteral<T>[] ]
return z.union( literals )
}
const MY_CONSTANTS = [ 'a', 'b', 1 ] as const
const unionType = unionOfLiterals( MY_CONSTANTS )
type UnionType = z.infer<typeof unionType>
// type UnionType = "a" | "b" | 1
console.log( unionType.parse( 'a' ) ) // a
console.log( unionType.parse( 'b' ) ) // b
console.log( unionType.parse( 1 ) ) // 1
console.log( unionType.safeParse( 'foo' ).success ) // false If you found my answer satisfactory, please consider supporting me. Even a small amount is greatly appreciated. Thanks friend! 🙏 |
Beta Was this translation helpful? Give feedback.
Is this what you are looking for?
If you found my answer satisfacto…