-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Description
I love this lib, simple and focused.
I think you may want to spend another hour of work to:
- add
QueryParamstype, modelled afterRouteParams - add documentation for
QueryParams&RouteParams - add documentation for how to type ReactRouter's
Routecomponent's params
User-land typesafe usage example of ReactRouter Route component:
import React from "react";
import { Route as RouteComponent, RouteProps, RouteComponentProps } from "react-router-dom";
import { RouteParams, Route } from "typesafe-react-router";
type QueryParams<T> = T extends Route<any, infer Y> ? Partial<Record<Y[number], string>> : never;
interface MatchProps<R extends Route<any, any>>
extends Omit<RouteProps, "path" | "render" | "component" | "children"> {
route: R;
component?: React.ComponentType<RouteComponentProps<RouteParams<R>>>;
render?: (
params: RouteParams<R> & QueryParams<R>,
allProps: RouteComponentProps<RouteParams<R>>
) => React.ReactNode;
children?: (props: RouteComponentProps<RouteParams<R>>) => React.ReactNode;
}
// Simple typesafe ReactRoute `Route` component wrapper. Not nestable in ReactRouter `Switch` component.
// `render` prop.
// Renders only when matching.
// Similar to `ReactRouter Route#render`, but first argument is params/search_params hash:
// Explicitely access match params/search_params hash.
// <Match route={Routes.project.template()} render={({ projectId }) => <Project projectId={projectId} />} />
// Project -since it is a function- gets the first render arg. (i.e. params/search_params) mixed in the props.
// So the previous example can be written:
// <Match route={Routes.project.template()} render={Project} />
// Explicitely access ReactRouter props (second arg.).
// <Match route={Routes.project.template()} render={(_, { history, location, match, staticContext }) => <Project projectId={match.params.projectId} /> } />
// `component` prop.
// Renders only when matching.
// Identical to `ReactRouter Route#component`:
// Project gets ReactRouter props mixed in his props. `projectId` is accessible with `props.match.params.projectId`.
// <Match route={Routes.project.template()} component={Project} />
// `children` prop
// ALWAYS renders
// Identical to `ReactRouter Route#children`. Only the "function as a children" form is typesafe.
// <Match route={Routes.project.template()}>
// {({ history, location, match, staticContext }) =>
// match ? <Project projectId={match.params.projectId} /> : null}
// </Match>
const Match = <R extends Route<any, any>>({
route,
render,
component,
...routeProps
}: MatchProps<R>) => (
<RouteComponent
{...routeProps}
path={route.template()}
render={props =>
render
? render({ ...props.match.params, ...route.parse(props.location.search) }, props)
: component
? React.createElement(component, props)
: undefined
}
/>
);
export default Match;Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels