Extract route params type (via Template Literal Types)
![Extract route params type (via Template Literal Types)](/content/images/size/w2000/2022/05/2022-05-05-09-47-50.png)
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
{};
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'>();
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.
Replace URL params to build link for navigation
// β
typesafe replace params via object with properties
const url = buildLink('/friends/:friendId/photos/:photoId', { friendId, photoId });
<Link to={url}>view photo</Link>