https://github.com/felipstein/zod-hookform-union-helper
TypeScript helper library to seamlessly integrate zod discriminated unions with react-hook-form, resolving common type issues.
https://github.com/felipstein/zod-hookform-union-helper
form-validation typescript typescript-union-errors union-type-errors union-type-validation zod zod-discriminated-uinon-type zod-union-issue
Last synced: 10 months ago
JSON representation
TypeScript helper library to seamlessly integrate zod discriminated unions with react-hook-form, resolving common type issues.
- Host: GitHub
- URL: https://github.com/felipstein/zod-hookform-union-helper
- Owner: Felipstein
- Created: 2023-11-01T15:39:53.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2023-11-01T15:57:51.000Z (over 2 years ago)
- Last Synced: 2024-11-21T08:38:50.192Z (over 1 year ago)
- Topics: form-validation, typescript, typescript-union-errors, union-type-errors, union-type-validation, zod, zod-discriminated-uinon-type, zod-union-issue
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/zod-hookform-union-helper
- Size: 37.1 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# `zod-hookform-union-helper`
## Introduction
Developers frequently face challenges when integrating `zod` with `react-hook-form`, particularly when working with discriminated unions.
## The Issue
When using discriminated unions with `zod` and `react-hook-form`, TypeScript often throws type errors that can be confusing. For instance:
Given a union type in `zod`:
```typescript
const FormCertificateSchemaCertificate = z.discriminatedUnion("certificate", [ ... ]);
```
And when integrating it with `react-hook-form`:
```tsx
{watch('certificate') === 'birth' && (
)}
```
TypeScript flags an error at `errors.birth?.message`, indicating that `birth` doesn't exist within `errors`. Technically, this is true until `certificate` is set to `birth`. This means even if your component's logic correctly recognizes the `birth` field once `certificate` is set, TypeScript doesn't acknowledge this initially, leading to unnecessary type errors.
## The Solution: `zod-hookform-union-helper`
The `zod-hookform-union-helper` library leverages TypeScript capabilities to consolidate fragmented error unions into one cohesive type.
### Installation:
```bash
npm install zod-hookform-union-helper
```
### Usage:
There are two primary ways to implement `zod-hookform-union-helper`:
#### 1. Using the `unifyErrors` function:
```tsx
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { unifyErrors } from 'zod-hookform-union-helper'
// ...
const {
formState: { errors },
} = useForm()
const errorsUnified = unifyErrors(errors) // use errorsUnified in your component
```
#### 2. Using TypeScript type casting:
```tsx
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import type { UnifiedErrors } from 'zod-hookform-union-helper'
// ...
const {
formState: { errors },
} = useForm()
const errorsUnified = errors as UnifiedErrors // use errorsUnified in your component
```
## Examples
Revisiting the scenario described in the "The Issue" section:
Without using `zod-hookform-union-helper`:
```tsx
{watch('certificate') === 'birth' && (
)}
```
With this setup, TypeScript throws a type error at `errors.birth?.message`.
Now, employing `zod-hookform-union-helper`:
```tsx
const errorsUnified = unifyErrors(errors);
{watch('certificate') === 'birth' && (
)}
```
In this instance, TypeScript acknowledges `errorsUnified.birth?.message` without any issue.
## Requirements
- TypeScript version 3.0 or higher.
## Contributing
Feedback and contributions are welcome! Please open an issue or submit a PR if you have suggestions, improvements, or bug fixes.