-
-
Notifications
You must be signed in to change notification settings - Fork 5
fix: PathParams type #4
base: master
Are you sure you want to change the base?
Conversation
This was my first time submitting a PR using the new VSCode editor built into Github. Worked well. |
Thank you! I think it's almost there, the only part that is not working now are optional path params, although I'm starting to doubt they ever worked correctly. I think they're not used very frequently. I imagine that is what the |
I think CI is failing due to an unrelated reason: we were pinning to a specific version of a library that hadn't been released yet, I can fix that. |
Interesting. I wasn't aware of the optional params feature and I didn't realize that so much documentation was behind the link to the Well modifying this PR to support optional path params should be easy enough. I haven't tested, but I think this code will handle optional params correctly: /** Split type `"one/:two/:three?/:four"` into `["one", ":two", ":three?", ":four"]` */
type SplitPath<S extends string> =
string extends S ? string[] :
S extends `${infer A}/${infer B}` ? [A, ...SplitPath<B>] :
[S];
/** Convert type `"one" | ":two" | ":three?" | ":four"` into `"two" | "four"` */
type ExtractRequiredParams<S extends string> =
string extends S ? string :
S extends `:${infer A}?` ? never :
S extends `:${infer A}` ? A :
never;
/** Convert type `"one" | ":two" | ":three?" | ":four"` into `"three"` */
type ExtractOptionalParams<S extends string> =
string extends S ? string :
S extends `:${infer A}?` ? A :
never;
/**
* Convert a route path string literal type such as "one/:two/:three?/:four"
* into a params interface like `{ two: string; three?: string; four: string }`
*/
export type PathParams<S extends string> = {
[P in ExtractRequiredParams<SplitPath<S>[number]>]: string;
} & {
[P in ExtractOptionalParams<SplitPath<S>[number]>]?: string;
}; I'm happy to update this PR with the necessary changes to support optional route params. This being said, having glanced over the |
I really appreciate the work so far, I think when we support optional
parameters and other simple regexes we will cover 99% of cases which is
good enough. The browser and CF workers are shipping their own native
path-to-regexp equivalent soon (I forget the name) which I think is a bit
more limited.
When someone wants to use the advanced features (e.g. using actual
patterns) they can annotate the type of that themselves (at worst something
like `Record<string,string>`.
I'm currently not near a computer so I'm not able to give the latest
revision a test run but will do so after Christmas :)
Thank you again!
…On Fri, 24 Dec 2021, 09:39 John, ***@***.***> wrote:
I think it's almost there, the only part that is not working now are
optional path params, although I'm starting to doubt they ever worked
correctly.
Interesting. I wasn't aware of the optional params feature and I didn't
realize that so much documentation was behind the path-to-regexp library
link.
Well modifying this PR to support optional path params should be easy
enough. I haven't tested, but I think this code will handle optional params
correctly:
/** Split type `"one/:two/:three?/:four"` into `["one", ":two", ":three?", ":four"]` */type SplitPath<S extends string> =
string extends S ? string[] :
S extends `${infer A}/${infer B}` ? [A, ...SplitPath<B>] :
[S];
/** Convert type `"one" | ":two" | ":three?" | ":four"` into `"two" | "four"` */type ExtractRequiredParams<S extends string> =
string extends S ? string :
S extends `:${infer A}?` ? never : S extends `:${infer A}` ? A : never;/** Convert type `"one" | ":two" | ":three?" | ":four"` into `"three"` */type ExtractOptionalParams<S extends string> = string extends S ? string : S extends `:${infer A}?` ? A : never;/** * Convert a route path string literal type such as "one/:two/:three" * into a params interface like `{ two: string; three: string }`
*/export type PathParams<S extends string> = {
[P in ExtractRequiredParams<SplitPath<S>[number]>]: string;} & {
[P in ExtractOptionalParams<SplitPath<S>[number]>]?: string;};
I'm happy to update this PR with the necessary changes to support optional
route params. This being said, having glanced over the path-to-regexp
library now, it looks like there are a lot of features in there that aren't
currently handled by the PathParams type. It's not clear to me if
typescript string literal types are capable of accurately modeling the
path-to-regexp options, but considering someone built a SQL database
using string type literals <https://github.com/codemix/ts-sql>, I'm
guessing it's possible. I'm not personally interested in trying to flesh
out this PR to fully model all the path-to-regexp options though. Are you
still interested in merging it?
—
Reply to this email directly, view it on GitHub
<#4 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAH5ZFQBKOTIHRQVHMSAMCLUSQWURANCNFSM5KRTXDOA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you commented.Message ID:
***@***.***>
|
(FYI, haven't forgotten about this--just been busy with the holidays. Might be another week or two before I can follow up.) |
Ok, I've updated this PR to support optional params in addition to required params. I think it's ready to merge. Separately, I think it's possible that the Aside: I was able to submit and update this PR entirely using Github's new vscode web editor. Pretty nice! |
Looks like the test is failing because |
This pull request fixes the
PathParams
type.The example shown in the docs has a type error in Typescript 4.4/4.5.
The expected type should include
lastName: string
.Here's a typescript playground reproduction.
This merge request fixes the issue so that PathParams is properly typed.
As a side note, it's unclear why
PathParams
is defined asinstead of simply
Since
{someKey: string} & {someKey?: string}
is always equivalent to just{someKey: string}
.