UNPKG

zod-refine

Version:

An adapter that allows using Zod schemas as Recoil Sync validators instead of Refine.

138 lines (107 loc) 3.21 kB
# `zod-refine` ![Github CI](https://github.com/brncsk/zod-refine/actions/workflows/release.yml/badge.svg) [![NPM version](https://badge.fury.io/js/zod-refine.svg)](https://www.npmjs.com/package/zod-refine) `zod-refine` is an adapter library that lets you use [Zod](https://github.com/colinhacks/zod) schemas for validating atom values in [Recoil Sync](https://recoiljs.org/docs/recoil-sync/introduction/) effects. Recoil Sync is an add-on library for [Recoil](https://recoiljs.org), Meta's fairly new-ish state management library for React. # Why? Recoil Sync provides its own type-refinement/validator library, called [Refine](https://recoiljs.org/docs/refine/Introduction), however Zod provides better TypeScript integration and more features, so there's that. # Installation ```sh npm i zod-refine yarn add zod-refine ``` # Usage `zod-refine`'s sole export is a function named `getRefineCheckerForZodSchema()`. It takes a single `Zod.Schema` (a.k.a. [`ZodType`](https://zod.dev/?id=constraining-allowable-inputs)) and returns the associated [Refine Checker](https://recoiljs.org/docs/refine/api/Checkers). The following is an introductory example on checking a Recoil [atom's](https://recoiljs.org/docs/basic-tutorial/atoms) value in a Recoil Sync [`syncEffect`](https://recoiljs.org/docs/recoil-sync/sync-effect). **Using Refine:** ```ts import { atom } from 'recoil'; import { syncEffect, refine } from 'recoil-sync'; const testAtom = atom<number>({ key: 'test', default: 0, key: 'test', effects: [ syncEffect({ refine: refine.number(), }), ], }); ``` **Using `zod-refine`:** ```ts import { atom } from 'recoil'; import { syncEffect } from 'recoil-sync'; import { z } from 'zod'; import { getRefineCheckerForZodSchema } from 'zod-refine'; const testAtom = atom<number>({ key: 'test', default: 0, effects: [ syncEffect({ refine: getRefineCheckerForZodSchema(z.number()), }), ], }); ``` # Advanced Usage ## Upgrading an atom's type One can [upgrade an atom's type](https://recoiljs.org/docs/recoil-sync/sync-effect#upgrade-atom-type) using Refine's `match()` and `asType()` checkers: ```ts const myAtom = atom<number>({ key: 'MyAtom', default: 0, effects: [ syncEffect({ refine: match( number(), asType(string(), x => parseInt(x)), asType(object({ value: number() }), x => x.value) ), }), ], }); ``` This idiom can be adapted to Zod using `z.union()` / `transform()`: ```ts const myAtom = atom<number>({ key: 'MyAtom', default: 0, effects: [ syncEffect({ refine: getRefineCheckerForZodSchema( z.union([ z.number(), z.string().transform(x => parseInt(x)), z.object({ value: z.number() }).transform(x => x.value), ]) ), }), ], }); ``` # API Reference ## `getRefineCheckerForZodSchema()` ```ts export function getRefineCheckerForZodSchema<S extends Schema>( schema: S ): Checker<z.infer<S>>; ``` # Known problems ## Error handling Refine can only handle a single error when reporting validation problems. When Zod reports multiple issues, `zod-refine` only passes the first one to Refine. # License MIT