iway1 / react-ts-form

https://react-ts-form.com
MIT License
2.01k stars 33 forks source link

issue: custom field component for a type z.number().int() is ignored when I have z.number() present #117

Open capaj opened 1 year ago

capaj commented 1 year ago

Version Number

1.6.4

Codesandbox/Expo snack

No response

Steps to reproduce

I have this mapping

export const JsonSchema = z.object({})
export const NullableDate = z.date().nullable()
export const CategoryId = z
  .number()
  .int()
  .refine((val) => val > 0)

const mapping = [
  [z.string(), TextField],
  [z.boolean(), CheckboxField],
  [z.number(), NumberField], // when I remove this line, component CategoryIdField renders for my schema
  [z.nativeEnum(AdminUserRoles), makeSelectFieldForEnum(AdminUserRoles)],
  [JsonSchema, JsonSchemaField] as const,
  [NullableDate, DateField] as const,
  [CategoryId, CategoryIdField] as const
] as const // 👈 `as const` is necessary

yet even when I use CategoryId in my zod schema, it is still rendering with NumberField

I will try to prepare a code sandbox

Expected behaviour

It should prefer the exact zod type rather than the generic z.number() field component

Relevant log output

No response

iway1 commented 1 year ago

I think this is what we want the behavior to be, since the schema is just a z.number() with some extra conditions - when checking against the mapping we just look for the zod type of the schema. This allows adding additional checks at the schema level

Should be able to use createUniqueFieldSchema() on CategoryId to make it map correctly:

export const CategoryIdSchema = createUniqueFieldSchema('category-id',  z
 .number()
 .int()
 .refine((val) => val > 0)
 )

This seems consistent with how other types work in the library - let me know if you think there's a reason z.number().int() should be considered as a something different from z.number().int() though. I'll leave open for now for discussion