vazco / uniforms

A React library for building forms from any schema.

Home Page:https://uniforms.tools

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unknown type error for nullable() and nullish()

dwidge opened this issue · comments

commented

problem

When we have a nullable() or nullish() zod field it throws 'unknown type'.

We can't use our main zod types for uniforms directly because we use null fields in the mysql database and endpoints. We use both types: undefined to mean unchanged or unknown, and null to mean the field is empty.

Maybe treat nullable the same as optional in the forms? Set the field to null if not entered by user?

workaround

Create separate zod types for uniforms with optional() instead of nullish() or nullable(). Replace undefined fields with null in the onSubmit handler. Keep them updated with the main schema.

packages

import ZodBridge from "uniforms-bridge-zod";
import { AutoForm } from "uniforms-mui";
commented

workaround

// ChatGPT

import z from "zod";

// Convert zod nullable types to optional types
export function convertNullableToOptional<T extends z.ZodRawShape>(
  schema: z.ZodObject<T>
): z.ZodObject<T> {
  const newShape: any = {};

  for (const key in schema.shape) {
    const field = schema.shape[key];

    if (field instanceof z.ZodNullable) {
      newShape[key] = field.unwrap();
      if (!(newShape[key] instanceof z.ZodArray))
        newShape[key] = newShape[key].optional();
      // .transform((x: any) => x ?? null);
    } else if (
      field instanceof z.ZodOptional &&
      field.unwrap() instanceof z.ZodNullable
    ) {
      newShape[key] = field.unwrap().unwrap();
      if (!(newShape[key] instanceof z.ZodArray))
        newShape[key] = newShape[key].optional();
      // .transform((x: any) => x ?? null);
    } else if (
      field instanceof z.ZodOptional &&
      field.unwrap() instanceof z.ZodArray
    ) {
      newShape[key] = field.unwrap();
    } else if (field instanceof z.ZodObject) {
      newShape[key] = convertNullableToOptional(field);
    } else {
      newShape[key] = field;
    }
  }

  return z.object(newShape) as z.ZodObject<T>;
}

problem

The transform() also causes unknown type error, so we can't return null, only undefined.