Skip to content

Instantly share code, notes, and snippets.

@vixeven
Created November 21, 2022 17:30
Show Gist options
  • Save vixeven/4d758542d5a6e0078d9b70ec9791bc46 to your computer and use it in GitHub Desktop.
Save vixeven/4d758542d5a6e0078d9b70ec9791bc46 to your computer and use it in GitHub Desktop.
type Endpoint =
| "/users/:userId"
| "/users/:userId/photos/:photoId"
| "/reviews";
type ParseUrlParams<url> = url extends `${infer path}(${infer optionalPath})`
? ParseUrlParams<path> & Partial<ParseUrlParams<optionalPath>>
: url extends `${infer start}/${infer rest}`
? ParseUrlParams<start> & ParseUrlParams<rest>
: url extends `:${infer param}`
? { [k in param]: string }
: {};
export function getQueryKey<
T extends Endpoint extends `/${string}` ? Endpoint : never
>(path: T, params: ParseUrlParams<T> = {}): [string] {
if (path.includes(":") && !params) {
throw new Error("Missing params");
}
// Replace all params with their values
let url = Object.entries<string>(params).reduce<string>(
(path, [key, value]) => path.replace(`:${key}`, value),
path
);
// Clean up the url
url = url.replace(/(\(|\)|\/?:[^\/]+)/g, "");
return [url];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment