Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

typed-route

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typed-route

Type safe routes

  • 1.0.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

typed-route

Type safe routes developed for React Router

Quick example:

// 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 = () => (
  <Router>
    <Route exact path={routes.list} component={ListPage} />
    <Route exact path={routes.item} component={ItemPage} />
    <Route exact path={routes.form.detail} component={FormDetailPage} />
    <Route exact path={routes.form.subForm} component={SubFormPage} />
  </Router>
);

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

type SubFormProps = RouteComponentProps<InferTypedRoute<typeof routes.form.subForm>>;

const SubFormPage: React.FC<SubFormProps> = ({ match }) => (
  <div>
    Subform params:
    { match.params.id }
    { match.params.sub }
  </div>
);

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

const Navigation = () => (
  <div>
      <Link to={reverseUrl(routes.item, { id: 1 })}>Link to item</Link>
      <Link to={reverseUrl(routes.form.subForm, { id: 2, sub: 'test' })}>Link to sub form</Link>
      {/* TS Error: Property 'id' is missing */}
      <Link to={reverseUrl(routes.form.subForm, { sub: 'test' })}>Error link</Link>
  </div>
);

Quick Start

Requirements

  • npm or Yarn
  • Node.js 10.0.0 or higher
  • Typescript 3.5.0 or higher

Installation

$ npm install typed-route

If you are using Yarn, use the following command.

$ 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

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

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

let route = typedRoute<'id'>('/item/:id');
type I1 = InferTypedRoute<typeof route>;
// { id: string }

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

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

const routes = {
  list: '/list',
  form: routeMap(typedRoute<'id'>('/form/:id'), {
    subForm: routeMap(typedRoute<'sub'>('/:sub'), {
      detail: '/detail',
    })
  })
};
type I5 = InferTypedRoute<typeof routes.form.subForm.detail>;
// { id: string; sub: string }

You can use it with react-router

type SubFormProps = RouteComponentProps<InferTypedRoute<typeof routes.form.subForm.detail>>;

const SubFormPage: React.FC<SubFormProps> = ({ match }) => (
  <div>
    Subform params:
    { match.params.id }
    { match.params.sub }
  </div>
);

InferRouteMap

Generates route map type params

const routes = {
  list: '/list',
  form: routeMap(typedRoute<'id'>('/form/:id'), {
    info: '/info',
    subForm: routeMap(typedRoute<'sub'>('/:sub'), {
      detail: '/detail',
    })
  })
};
type RoutesParams = InferRouteMap<typeof routes>;
/* {
 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

type SubFormProps = RouteComponentProps<RoutesParams['form']['subForm']['detail']>;

const SubFormPage: React.FC<SubFormProps> = ({ match }) => (
  <div>
    Subform params:
    { match.params.id }
    { match.params.sub }
  </div>
);

Keywords

FAQs

Package last updated on 18 Sep 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc