Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/febeling/nextjs14-shadcnui-zod-rhf-drizzle-testcase
Reproduce a problem with typesafe editing of model entities nullable text fields.
https://github.com/febeling/nextjs14-shadcnui-zod-rhf-drizzle-testcase
drizzle-orm react-hook-form shadcn typescript zod
Last synced: 8 days ago
JSON representation
Reproduce a problem with typesafe editing of model entities nullable text fields.
- Host: GitHub
- URL: https://github.com/febeling/nextjs14-shadcnui-zod-rhf-drizzle-testcase
- Owner: febeling
- Created: 2024-04-04T11:59:58.000Z (10 months ago)
- Default Branch: master
- Last Pushed: 2024-04-04T20:25:48.000Z (10 months ago)
- Last Synced: 2024-11-12T16:19:39.078Z (2 months ago)
- Topics: drizzle-orm, react-hook-form, shadcn, typescript, zod
- Language: TypeScript
- Homepage:
- Size: 87.9 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome - febeling/nextjs14-shadcnui-zod-rhf-drizzle-testcase - Reproduce a problem with typesafe editing of model entities nullable text fields. (TypeScript)
README
# README
## Issue
Reproduce a problem with typesafe editing of model entities nullable text fields.
This app reproduces this problem in a somewhat minimal way. It's built using Nextjs 14, Drizzle ORM, Zod validations derived from schema, Shadcn/ui forms, react-hook-form for a minimal CRUD UI.
## Goal
The goal is typesafety from the UI to the database schema, while creating, validating, and editing database entries.
## Problem
The form fields in Shadcn-ui/react-hook-form don't allow null values. This isn't surprising, because text inputs can't represent them any different from empty strings. But this conflicts with what the database derived validation schema and types expect.
It results in type errors and plenty of empty strings in the database.
## What to look for?
This problem manifests itself in two ways; firstly this warning
```shell
npx tsc --noEmit
src/app/new/page.tsx:70:25 - error TS2322: Type 'string | null | undefined' is not assignable to type 'string | number | readonly string[] | undefined'.
Type 'null' is not assignable to type 'string | number | readonly string[] | undefined'.70 value={field.value} // <-
~~~~~node_modules/.pnpm/@[email protected]/node_modules/@types/react/index.d.ts:3332:9
3332 value?: string | readonly string[] | number | undefined;
~~~~~
The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & InputProps & RefAttributes'Found 1 error in src/app/new/page.tsx:70
```In short, for field `email` the user model has type `string | null | undefined` (derived from the db schema), while the form field can't handle the `null` and expects `string | readonly string[] | number | undefined` instead.
Secondly, in new records always containing empty string where there is no input.
## Are we on the right track?
Is it correct to have a nullable database column? Yes, usually we want nullable database columns for string fields in order to make queries simpler (e.g. `WHERE email IS NULL`).
## Workaround
There are workarounds. It is possible to change the code in line 70 (see above) to the follwing, and slience the warning:
```jsx
value={field.value ?? ''}
```That makes the typechecker happy and removes the warning. But it shouldn't be necessary when types are correct, and we go to all that length for them.
For the second part, it is possible to transform during validation by using the `refine` feature of Zod. This is the code to add to `src/lib/schema.ts`.
```ts
const nullifyEmptyString = (value: string) =>
typeof value === "string" && value.length === 0 ? null : value;export const InsertJobSchema = createInsertSchema(jobs, {
description: schema =>
schema.description.trim().transform(nullifyEmptyString),
});
```The function `createInsertSchema` is imported from `drizzle-zod`, a package by the Drizzle team.
This transform would need to be applied to each field that is nullable.