fabien0102 / ts-to-zod

Generate zod schemas from typescript types/interfaces
MIT License
1.17k stars 65 forks source link

Incorrect Conversion of Array with Rest Element to Zod Schema #256

Closed TheCrowdsecMatt closed 1 month ago

TheCrowdsecMatt commented 2 months ago

Bug description

Incorrect conversion of an array type with a rest element into a Zod schema that includes z.any(), which is not the intended behavior.

Input

export interface Resident {
    id: string;
    name: string;
    addresses: [Address, ...Address[]];
}

export interface Address {
  street:string;
  zipCode: number;
};

Expected output

import { z } from "zod"

export const addressSchema = z.object({
  street: z.string(),
  zipCode: z.number()
})

export const residentSchema = z.object({
  id: z.string(),
  name: z.string(),

  // Could also be -> abilitations: z.array(abilitationSchema).min(1);
  addresses: z.array(addressSchema).nonempty() 
})

Actual output

import { z } from "zod"

export const addressSchema = z.object({
  street: z.string(),
  zipCode: z.number()
})

export const residentSchema = z.object({
  id: z.string(),
  name: z.string(),
  addresses: z.tuple([addressSchema, z.any()])
})

Versions

tvillaren commented 1 month ago

Hello @TheCrowdsecMatt and thanks for reporting.

I see in Zod document about tuples that the rest operator is supported so I think the expected output should be

export const residentSchema = z.object({
  id: z.string(),
  name: z.string(),
  addresses: z.tuple(addressSchema).rest(addressSchema);
})
TheCrowdsecMatt commented 1 month ago

Hello @tvillaren I agree your suggestion makes sense also 👍 Thanks for the PR creation.

tvillaren commented 1 month ago

Thanks, I released it in 3.10.0 https://github.com/fabien0102/ts-to-zod/pull/258