npm.io
0.1.0 • Published 20h ago

@js-fns/coerce

Licence
MIT
Version
0.1.0
Deps
0
Size
33 kB
Vulns
0
Weekly
0
Stars
9

@js-fns/coerce

@js-fns/coerce is a lightweight, near-zero overhead alternative to Zod and Valibot.

Unlike these libraries, @js-fns/coerce focuses on a single task: ensuring the data corresponds to the types.

It uses built-in JavaScript features to coerce whatever you pass to it, keeping the library small and fast.

import { coercer } from "@js-fns/coerce";

interface User {
  name: string;
  email: string;
  age?: number;
}

const coerceUser = coercer<User>(($) => ({
  name: String,
  email: String,
  age: $.Optional(Number),
}));

const user = coerceUser({ name: "Sasha", age: "37" });
//=> { name: "Sasha", email: "", age: 37 }

It accepts the desired shape type as the generic argument and type-checks the defined schema against it.

But just like the alternatives, it allows inferring types from the schema:

import { coercer } from "@js-fns/coerce";

const coerceUser = coercer.infer(($) => ({
  name: String,
  email: String,
  age: $.Optional(Number),
}));

type User = coercer.Infer<typeof coerceUser>;
// { name: string, email: string, age?: number }

It also accepts FormData making it ideal when working with forms, especially inside of React Server Components:

import { coercer } from "@js-fns/coerce";

const coerceForm = coercer({
  email: String,
  password: String,
});

function SignInForm() {
  return (
    <form
      action={async (formData) => {
        "use server";
        const form = coerceForm(formData);
        await signIn(form);
      }}
    >
      <input name="email" type="email" required placeholder="Email" />
      <input name="password" type="password" required placeholder="Password" />
      <button>Sign in</button>
    </form>
  );
}

You can also use constructors as coercers, that is useful, for example, when working with File:

import { coercer } from "@js-fns/coerce";

const coerceFile = coercer({
  file: File,
});

function UploadForm() {
  return (
    <form
      action={async (formData) => {
        "use server";
        const form = coerceFile(formData);
        await upload(form);
      }}
    >
      <input name="file" type="file" required />
      <button>Upload</button>
    </form>
  );
}

It will check if the value is an instance of File, and if not, it will try to call new File() without parameters.

Getting Started

Installation

The package is available as a standalone npm package:

npm install @js-fns/coerce

It is also available as a part of the js-fns collection:

npm install js-fns

Changelog

See the changelog.

License

MIT Sasha Koss