-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recursive solution for Transform Path Parameters from Strings to Objects #15
Comments
@jbalsas I like the solution. I too feel its easier to reason with. I struggled with the I definitely like the recursive approach better. type Url = "/home?search=hello&count=100";
type QueryParams<T> = T extends `${string}?${infer QueryParams}`
? QueryParams
: never;
type ExtractQuery<T> =
T extends `${infer Param}=${infer Value}&${infer RestOfQueries}`
? Param | ExtractQuery<RestOfQueries>
: T extends `${infer Param}=${infer Value}`
? Param
: never;
type ExtractQueryParams<T> = {
[K in ExtractQuery<T>]: string;
};
type SearchQueryObject = ExtractQueryParams<QueryParams<Url>>; Nicely works for extracting query params too |
Nice! I think Split is obviously sort of a more refined version of this recursive approach. I gave the utility approach a try and came up with this, without the key remapping which I guess is sort of the thing that immediately clicked for me but now it's present when I think about this. import { Equal, Expect } from '../helpers/type-utils';
type UserPath = '/users/:id';
type UserOrganisationPath = 'a/users/:id/organisations/:organisationId';
type UserOrganisationTeamPath =
'/users/:id/organisations/:organisationId/teams/:teamId';
type Split<
T extends string,
Sep extends string
> = T extends `${infer Param}${Sep}${infer Rest}`
? `${Param}` | Split<Rest, Sep>
: `${T}`;
type Trim<
T extends string,
Char extends string
> = T extends `${Char}${infer Rest}` ? Rest : T;
type StartsWith<
T extends string,
Char extends string
> = T extends `${Char}${string}` ? T : never;
type ExtractPathParams<T extends string> = {
[K in Trim<StartsWith<Split<T, '/'>, ':'>, ':'>]: string;
};
type tests = [
Expect<Equal<ExtractPathParams<UserPath>, { id: string }>>,
Expect<
Equal<
ExtractPathParams<UserOrganisationPath>,
{ id: string; organisationId: string }
>
>,
Expect<
Equal<
ExtractPathParams<UserOrganisationTeamPath>,
{ id: string; organisationId: string; teamId: string }
>
>
]; |
Hi @mattpocock!!
First of all, thanks so much for these materials you put together. I don't think I've become a wizard yet, but going through the topics and exercises has been quite fun and I feel like I've learned a lot from it already!! 🤯 😍
I just finished watching
Transform Path Parameters from Strings to Objects
. I didn't think to use theS.Split
helper, so I came up with a recursive solution that felt easier to reason with (for me that I wrote it, of course! 😂)Just pasting it here in case you think something like that might help others in the future and curious to know how you think it compares with the proposed solution ❤️
The text was updated successfully, but these errors were encountered: