Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/atrue/typed-route

Typesafe routes developed for React Router
https://github.com/atrue/typed-route

react-router route router typescript url

Last synced: about 1 month ago
JSON representation

Typesafe routes developed for React Router

Awesome Lists containing this project

README

        

typed-route

Type safe routes developed for React Router

Quick example:
```tsx
// constants/routes.ts
import { typedRoute, routeMap } from 'typed-route';

export const routes = {
list: '/list',
item: typedRoute<'id'>('/item/:id'),
form: routeMap(typedRoute<'id'>('/form/:id'), {
detail: '/detail',
subForm: typedRoute<'sub'>('/:sub')
})
};

// routes.tsx
import { routes } from './constants/routes';

const Routes = () => (






);

// pages/sub-form.tsx
import { InferTypedRoute } from 'typed-route';
import { RouteComponentProps } from 'react-router-dom';
import { routes } from '../constants/routes';

type SubFormProps = RouteComponentProps>;

const SubFormPage: React.FC = ({ match }) => (


Subform params:
{ match.params.id }
{ match.params.sub }

);

// navigation.tsx
import { reverseUrl } from 'typed-route';
import { routes } from './constants/routes';

const Navigation = () => (


Link to item
Link to sub form
{/* TS Error: Property 'id' is missing */}
Error link

);

```

## Quick Start
### Requirements
- npm or Yarn
- Node.js 10.0.0 or higher
- Typescript 3.5.0 or higher

### Installation
```bash
$ npm install typed-route
```

If you are using Yarn, use the following command.

```bash
$ yarn add typed-route
```

## Usage

### typedRoute
`typedRoute` - generic function creates string with saved context

`typedRoute<'name'>('/:name')` - creates a string route with one param `{ name: string }`

`typedRoute<'id' | 'name'>('/:id/:name')` - creates a string route with a few params `{ id: string, name: string }`

`typedRoute<'id', 'name'>('/:id/:name?')` - you can add optional params `{ id: string, name?: string }`

### routeMap
Creates a route map merging all routes string and contexts

```ts
let routes;
routes = routeMap('/base', {
page1: '/page1',
page2: routeMap('/page2', {
info: '/info',
form: '/form'
})
});
console.log(routes);
/* {
index: '/base',
page1: '/base/page1',
page2: {
index: '/base/page2',
info: '/base/page2/info',
form: '/base/page2/form'
}
} */

```

### reverseUrl
Type safe function generates an url using typed route and route params
```ts
reverseUrl(
typedRoute('/item'),
); // item

reverseUrl(
typedRoute<'id'>('/item/:id'),
{ id: 1 }
); // item/1

reverseUrl(
typedRoute<'id'>('/item/:id'),
); // TS Error

reverseUrl(
typedRoute<'id'>('/item/:id'),
{}
); // TS Error: Property 'id' is missing

reverseUrl(
typedRoute<'id' | 'optional'>('/item/:id/:second'),
{ id: 1, second: 2 }
); // item/1/2

reverseUrl(
typedRoute<'id', 'optional'>('/item/:id/:optional?'),
{ id: 1 }
); // item/1

reverseUrl(
typedRoute<'id', 'optional'>('/item/:id/:optional?'),
{ id: 1, optional: 'test' }
); // item/1/test
```

### InferTypedRoute
Infer params from types route
```ts
let route = typedRoute<'id'>('/item/:id');
type I1 = InferTypedRoute;
// { id: string }

route = typedRoute<'id' | 'second'>('/item/:id/:second');
type I2 = InferTypedRoute;
// { id: string; second: string }

route = typedRoute<'id', 'optional'>('/item/:id/:optional?');
type I3 = InferTypedRoute;
// { id: string; optional?: string }

const routes = {
list: '/list',
form: routeMap(typedRoute<'id'>('/form/:id'), {
subForm: routeMap(typedRoute<'sub'>('/:sub'), {
detail: '/detail',
})
})
};
type I5 = InferTypedRoute;
// { id: string; sub: string }
```
You can use it with react-router
```tsx
type SubFormProps = RouteComponentProps>;

const SubFormPage: React.FC = ({ match }) => (


Subform params:
{ match.params.id }
{ match.params.sub }

);
```

### InferRouteMap
Generates route map type params
```ts
const routes = {
list: '/list',
form: routeMap(typedRoute<'id'>('/form/:id'), {
info: '/info',
subForm: routeMap(typedRoute<'sub'>('/:sub'), {
detail: '/detail',
})
})
};
type RoutesParams = InferRouteMap;
/* {
list: object;
form: {
index: { id: string };
info: { id: string };
subForm: {
index: { id: string };
detail: { id: string; sub: string }
}
}
*/
```
And you can use it with react-router instead of InferTypedRoute
```tsx
type SubFormProps = RouteComponentProps;

const SubFormPage: React.FC = ({ match }) => (


Subform params:
{ match.params.id }
{ match.params.sub }

);
```