- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 167
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
TypeScript: Infer params from path #211
TypeScript: Infer params from path #211
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
types/index.d.ts
Outdated
export interface RouteProps<RoutePath extends Path = Path> { | ||
children?: ((params: ExtractRouteParams<RoutePath>) => ReactNode) | ReactNode; | ||
path?: RoutePath; | ||
component?: ComponentType<RouteComponentProps<ExtractRouteParams<RoutePath>>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if there is any way to keep the backward compatibility for users who want to manually type their params, like:
Route<CustomParams> // params is of type `CustomParams`
Route // the type of params is inferred from path
Maybe we could move RoutePath
to the second type argument and provide a default first argument like so:
export function Route<T extends DefaultParams = null, RoutePath extends Path = Path>(
But I have a little experience, so not sure if this will work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any way to make the same trick for for the useRoute
hook:
const [match, params] = useRoute("/app/:user") // params has the right type
Hi, I created another PR (not sure how to handle such cases as it's based on the commits of this one): #217 that contains the changes that you mentioned in the comments (backward compatibility and @itsMapleLeaf Feel free to copy the commit and include/cherry-pick it in your PR, you did most of the work, don't want to take credit for it. |
Thanks for that, I didn't have the time to come back to this 😅 Went ahead and cherry-picked it |
@itsMapleLeaf Tested it and it works fine! Let's add this test case and we should be good to go. diff --git a/types/type-specs.tsx b/types/type-specs.tsx
index 81dae1e..2e2dd1e 100644
--- a/types/type-specs.tsx
+++ b/types/type-specs.tsx
@@ -90,7 +90,13 @@ const invalidParamsWithGeneric: Params<{ id: number }> = { id: 13 }; // $ExpectE
// for pathToRegexp matcher
<Route path="/:user([a-z]i+)/profile/:tab/:first+/:second*">
- {({ user, tab, first, second }) => `${user}, ${tab}, ${first}, ${second}`}
+ {({ user, tab, first, second }) => {
+ user; // $ExpectType string
+ tab; // $ExpectType string
+ first; // $ExpectType string
+ second; // $ExpectType string | undefined
+ return `${user}, ${tab}, ${first}, ${second}`;
+ }}
</Route>;
/* |
@graphman65 Done 👍 For future reference, reviews have a "suggestion" feature, which makes it a lot easier to suggest changes, where I can add them in with a button click |
Co-authored-by: Sébastien Lacoste <graphman65@gmail.com>
types/index.d.ts
Outdated
export interface RouteProps<RoutePath extends Path = Path> { | ||
children?: ((params: ExtractRouteParams<RoutePath>) => ReactNode) | ReactNode; | ||
path?: RoutePath; | ||
component?: ComponentType<RouteComponentProps<ExtractRouteParams<RoutePath>>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @itsMapleLeaf @graphman65 !
Codecov Report
@@ Coverage Diff @@
## master #211 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 7 7
Lines 250 250
Branches 50 50
=========================================
Hits 250 250
Continue to review full report at Codecov.
|
Just released this change as an alpha version Tried making a simple sandbox, but it doesn't seem to be working, https://codesandbox.io/s/little-fire-7bi1w?file=/src/App.tsx:410-415 |
I just created a sample project using |
Ok so I investigated and this is an issue in codesanbox, not wouter. The page is trying to load this file: But when I set the version of wouter to 2.7.4 it's working just fine and loading this file successfully. Looks like they are caching type info and it's not yet available for the new release. I found a lot of issues mentioning this error and looks like it got fixed at some point but some users started to face the issue again 5 days ago. (codesandbox/codesandbox-client#5502). |
One thing I've realised is that we still need proper types for the Preact version, which is distributed as a separate npm package P.S. Seems like supporting type definitions is becoming a bit PITA, so I'm really thinking about converting the source code into TypeScript in v3 of the library 🤔 |
Closes #210
This will probably be a breaking change for TS users who manually typed their path params, I'm not sure if that warrants a major 🤔 Open to alternative approaches as well.