Skip to content

Utility library for working with FormData in Typescript

License

Notifications You must be signed in to change notification settings

k1eu/typed-formdata

Repository files navigation

typed-formdata

typed-formdata is a utility library for working with FormData in Typescript.

In a nutshell, Typed FormData allows you to:

  • Work with FormData with strongly typed fields
  • Helpful for both Frontend and Backend work with FormData
  • Integrate it with Full stack typescript frameworks like Remix, Next.js, Nest.js
  • It is a drop-in replacement for FormData
  • It is built on top of the native FormData interface
  • Parse the formData body according to schema (WIP)

Installation

npm install @k1eu/typed-formdata
yarn add @k1eu/typed-formdata
pnpm add @k1eu/typed-formdata
bun add @k1eu/typed-formdata

Overview

Package can help you both on Frontend and Backend side of the application. It provides a TypedFormData class and parser functions for Request and FormData. Of course it is advised to have a validation layer in your backend until we have a schema validator implemented in the library.

Request handler:

import { TypedFormData } from "@k1eu/typed-formdata";

type IncomingData = {
  resourceId: string;
  file: File;
};

export const handler = async (req: Request) => {
  const formData = parseFormDataRequest<IncomingData>(req);
  const resourceId: string = formData.get("resourceId");
  const file: File = formData.get("file");
  const age: string = formData.get("age"); // Type Error! Age doesn't exist in IncomingData

  saveFile(file, resourceId);

  return new Response(
    `Hello your file ${file.name} is saved for the resource ${resourceId}`
  );
};

Frontend form:

import { TypedFormData } from "@k1eu/typed-formdata";

type MyFormData = {
  login: string;
  password: string;
};

function MyPage() {
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        const formData = new TypedFormData<MyFormData>(e.currentTarget);
        const login: string = formData.get("login");
        const password: string = formData.get("password");
        loginAndSubmit(login, password);
      }}
    >
      <input type="login" name="login" />
      <input type="password" name="password" />
      <button type="submit">Submit</button>
    </form>
  );
}

Remix action:

import { TypedFormData } from "@k1eu/typed-formdata";

type FormFields = {
  login: string;
  password: string;
};

export async function action({ request }: ActionArgs) {
  const formData = parseFormDataRequest<FormFields>(request);
  const login: string = formData.get("login");
  const password: string = formData.get("password");
  const file = formData.get("file"); // Type Error!
  loginAndSubmit(login, password);
  return redirect("/success");
}

export default function MyPage() {
  return (
    <main>
      <Form method="post">
        <input type="login" name="login" />
        <input type="password" name="password" />
        <button type="submit">Submit</button>
      </Form>
    </main>
  );
}

Other Parser functions:

// parseFormData
import { parseFormData } from "@k1eu/typed-formdata";

type FormFields = {
  resourceId: string;
  file: File;
};

const formData = new FormData(document.querySelector("form"));
const typedFormData = await parseFormData<FormFields>(formData);

// same as
// const typedFormData = new TypedFormData(document.querySelector("form") as HTMLFormElement);

License

See LICENSE

About

Utility library for working with FormData in Typescript

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published