Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fredericoo/react-router-typesafe
just the way you wanted React Router to work with TypeScript.
https://github.com/fredericoo/react-router-typesafe
react react-router react-router-dom react-router-dom-v6 router typescript
Last synced: 1 day ago
JSON representation
just the way you wanted React Router to work with TypeScript.
- Host: GitHub
- URL: https://github.com/fredericoo/react-router-typesafe
- Owner: fredericoo
- Created: 2023-07-16T12:18:17.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-06-20T20:19:52.000Z (7 months ago)
- Last Synced: 2025-01-19T19:51:32.360Z (7 days ago)
- Topics: react, react-router, react-router-dom, react-router-dom-v6, router, typescript
- Language: TypeScript
- Homepage:
- Size: 283 KB
- Stars: 107
- Watchers: 1
- Forks: 3
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# React Router Typesafe
React Router Typesafe is a minimal (235 bytes gzipped) patch built upon [react-router](https://github.com/remix-run/react-router) to add type-safety via the use of generics. It brings type functionality closer to Remix, the full-stack framework from the same authors.
## Getting Started
Install the package:
```bash
npm install react-router-typesafe
```Replace your imports from `react-router` to `react-router-typesafe`:
```diff
- import { defer, useLoaderData, useActionData } from "react-router";
+ import { defer, useLoaderData, useActionData } from "react-router-typesafe";
```## Usage
### useLoaderData / useActionData
```tsx
import { useLoaderData, useActionData, LoaderFunction, ActionFunction } from 'react-router-typesafe';const loader = (() => ({ message: 'Hello World' })) satisfies LoaderFunction;
const action = (() => ({ ok: true })) satisfies ActionFunction;
const Component = () => {
const data = useLoaderData();
const actionData = useActionData();return
{data.message};
};
```> **Warning**
> Do not annotate the type of the loader/action function. It will break the type-safety. Instead rely on either the `satisfies` keyword from Typescript 4.9 onwards, or the `makeLoader` / `makeAction` utilities proveded by this library.## Utilities
### makeLoader / makeAction
The `makeLoader` and `makeAction` utils replace the need for the `satisfies` keyword without adding any runtime overhead.
```tsx
import { makeLoader, makeAction } from 'react-router-typesafe';const loader = makeLoader(() => ({ message: 'Hello World' }));
const action = makeAction(() => ({ ok: true }));
```### typesafeBrowserRouter ❇️ NEW
The `typesafeBrowserRouter` is a wrapper around `createBrowserRoute` that returns a `href` function in addition to the routes.
It’s easy to incrementally adopt, and you can use `href` anywhere, not just in `` components.
Set up your routes like this:
```diff
- import { createBrowserRouter } from "react-router-dom";
+ import { typesafeBrowserRouter } from "react-router-typesafe";- export const router = createBrowserRouter([
+ export const { router, href } = typesafeBrowserRouter([
{ path: "/", Component: HomePage },
{ path: "/projects/:projectId", Component: ProjectPage },
]);
```- ✅ No need to change your existing `` components.
- ✅ URL params are inferred and type-checked.
- ✅ Supports query params and URL hash
- ✅ Refactor-friendly: **Rename Symbol** on the route path and it’ll be updated everywhere.Then use `href` to generate URLs:
```tsx
import { Link } from 'react-router-dom';
import { href } from './router';const ProjectCard = (props: { id: string }) => {
return (
Project {projectId}
);
};
```## Contributing
Feel free to improve the code and submit a pull request. If you're not sure about something, create an issue first to discuss it.
## Functions
| Status | Utility | Before | After |
| ------ | ----------------------- | ---------- | ------------------------------------------------------------ |
| ✅ | `defer` | `Response` | Generic matching the first argument |
| | `json` | `Response` | Serialized data passed in |
| ✅ | `useLoaderData` | `unknown` | Generic function with the type of the loader function passed |
| ✅ | `useActionData` | `unknown` | Generic function with the type of the action function passed |
| ✅ | `useRouteLoaderData` | `unknown` | Generic function with the type of the loader function passed |
| NEW | `makeLoader` | | Wrapper around `satisfies` for ergonomics |
| NEW | `makeAction` | | Wrapper around `satisfies` for ergonomics |
| NEW | `typesafeBrowserRouter` | | Extension of `createBrowserRouter` |## Patched components
| Status | Component | Before | After |
| ------ | --------- | --------------------------------------------- | --------------------------------------------- |
| ✅ | `` | children render props would be typed as `any` | Generic component makes render props typesafe |## About
React Router is developed and maintained by [Remix Software](https://remix.run) and many [amazing contributors](https://github.com/remix-run/react-router/graphs/contributors).