fabien0102 / ts-to-zod

Generate zod schemas from typescript types/interfaces
MIT License
1.2k stars 66 forks source link

Improvements for using discriminatedUnion #270

Open Ilrilan opened 1 month ago

Ilrilan commented 1 month ago

Feature description

Sometimes we have a union types with discriminated union, Zod can parse this case with help of discriminator, boosting performance. Can i modify configuration of ts-to-zod for customizing result schema now, or this feature need some enchancements of tool code?

Input

// typescript type or interface causing the output
type MyApiResult = { type:'A', foo: string } | { type:'B', bar: integer } | { type: 'C', baz: boolean }

Output

z.discriminatedUnion("type", [
  z.object({ type: z.literal("A"), foo: z.string() }),
  z.object({ type: z.literal("B"), bar: z.integer() }),,
  z.object({ type: z.literal("C"), bar: z.boolean() }),
])
tvillaren commented 2 weeks ago

Hey @Ilrilan,

This is not implemented in the lib yet.

We would need to give a hint to ts-to-zod as to which property should be used as the discriminator. For instance, relying on the JSDocTag syntax we use:

/**
 * @discriminator type
 */
type MyApiResult = { type:'A', foo: string } | { type:'B', bar: number } | { type: 'C', baz: boolean }

Would that make sense?

Ilrilan commented 2 weeks ago

Yes, this variant will be good solution.

Artemnsk commented 2 weeks ago

Hey! May such features be available via both JSDoc and some cli option? As an alternative way to pass these hints. This cli option may be just a path to a config file with such hints in some format (as it may appear to be messy to pass such a big instructions "as is" via cli).

I'm asking about it because I have already auto-generated (swagger) ts file and I would prefer to not touch the file itself before applying ts-to-zod to it. Sure I can make such changes to my file "on fly" and pipe to ts-to-zod, but it may be not that user-friendly. 🙂 Thanks in advance!