From 2eb31f8dbb814e4ebf28d2198ebbba1d88fc1607 Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Fri, 5 Jan 2024 15:11:43 +0100 Subject: [PATCH] Make passing parameters to `generateEncodedPath()` type-safe (#25944) Signed-off-by: Jon Koops --- .../admin-ui/src/utils/generateEncodedPath.ts | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/js/apps/admin-ui/src/utils/generateEncodedPath.ts b/js/apps/admin-ui/src/utils/generateEncodedPath.ts index 98e1ce27d6..d708699c52 100644 --- a/js/apps/admin-ui/src/utils/generateEncodedPath.ts +++ b/js/apps/admin-ui/src/utils/generateEncodedPath.ts @@ -1,17 +1,39 @@ -import { generatePath } from "react-router-dom"; +import { generatePath, type PathParam } from "react-router-dom"; -export type PathParam = { [key: string]: string }; +/** + * Represents an object that contains the parameters to be included in a path. + * + * @example + * const params: PathParams<"/user/:id"> = { id: "123" }; + */ +export type PathParams = { + [key in PathParam]: string; +}; +/** + * Generates a path that represents the given path template with parameters interpolated and encoded in it, so that it can safely used in a URL. + * + * @param originalPath - The path template to use to generate the path. + * @param params - An object that contains the parameters to be included in the path. + * + * @example + * const path = "/user/:id"; + * const params = { id: "123" }; + * const encodedPath = generateEncodedPath(path, params); + * // encodedPath will be "/user/123" + */ export function generateEncodedPath( originalPath: Path, - params: PathParam, + params: PathParams, ): string { - const encodedParams: PathParam = {}; + // Clone the params object so we don't mutate the original. + const encodedParams = structuredClone(params); - Object.entries(params).forEach( - ([k, v]) => (encodedParams[k] = encodeURIComponent(v)), - ); + // Encode each param in the path so that it can be used in a URL. + for (const key in encodedParams) { + const pathKey = key as PathParam; + encodedParams[pathKey] = encodeURIComponent(encodedParams[pathKey]); + } - //TODO: Fix type once https://github.com/remix-run/react-router/pull/10719 is merged. - return generatePath(originalPath, encodedParams as any); + return generatePath(originalPath, encodedParams); }