Extract route params type (via Template Literal Types)

TypeScript 4.1 introduced an awesome concept of template literal types which allows us to parse literal types and extract their parts as types for further manipulations.

The most prominent use case of this approach for frontend is to get types of parameters from URL path.

ExtractRouteParams type

type ExtractRouteParams<T extends string> = string extends T
  ? {}
  : // we have start/:oneId/restOfUrl
  T extends `${string}:${infer Param}/${infer Rest}`
  ? { [k in Param | keyof ExtractRouteParams<Rest>]: string }
  : // we only have start/:oneId
  T extends `${string}:${infer Param}`
  ? { [k in Param]: string }
  : // nothing found
    {};
base generic type ExtractRouteParams

This is basic implementation of generic type to infer params from URL according to param pattern :param which works good for any string length due to recursion.

Use cases

Create custom React hook which will return existing params for current URL

// βœ… typed params infered from literal string
const { friendId, photoId } = useTypedParams<'/friends/:friendId/photos/:photoId'>();
custom React hook useTypedParams

Usually, you will run this hook inside a component of a specific page like useTypedParams<Routes.somePage>(); so generic can infer params from its type argument = literal string from app-wide constant of all routes.

// βœ… typesafe replace params via object with properties
const url = buildLink('/friends/:friendId/photos/:photoId', { friendId, photoId });

<Link to={url}>view photo</Link>
generate link from path and params