-
Notifications
You must be signed in to change notification settings - Fork 57
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
Extended path parameter type-safety #122
Comments
Hey @janbuchar, could you please give an example with some context of the router functions/hooks you're using? From what I understand, the params type would always be a Related to that, as I'm considering supporting type-safe search params - which similar to path param, derived from the URL and location state - would be a flexible type. |
A concise example would be a route such as type PathParams {
articleId: number
} somewhere in the page file and then call Does this make sense? Of course, doing something similar for search params would also be helpful. But if that was possible, I think it would be even more justified to want the same for path parameters - there is no fundamental difference between these two. |
@janbuchar that's exactly what I thought about as well. But what I'm concerned about is on the runtime level all params would be strings, so declaring a param as number would be only on the type level. As an example: export type Params = { id: number }
const params = useParams('/invoice/:id')
// ^? { id: number }
typeof params.id === 'string' I'm concerned about the potential mismatch here, please let me know what you think. Maybe the search params can be handled differently if somehow values are decoded/encoded to preserve the types. I haven't tried something similar before. |
I'm glad I'm not the only one who would consider this useful. I believe there'd have to be some runtime encoder/decoder for types like |
@janbuchar the problem even if we have a route-based type for params and search params, the built-in I believe the codegen would only make it easier, it can start as something similar to |
I see. Yes, having runtime conversion of path or search parameters rules out using anything directly imported from react-router, tanstack/router and the like. Or, using those just forfeits the type safety added by the runtime conversion. Having something like the package you linked is very close to what I had in mind 🙂 |
I love that I'm not the only one that was thinking about this. Personally, I use this snippet to address this problem, for me it's enough, but maybe for you it might become inspiration. useParam.ts import { useParams } from "react-router-dom"
function useParam<N extends boolean = false>(paramKey: string, numeric?: N): N extends true ? number : string {
const params = useParams()
const paramValue = params[paramKey]
if (paramValue == null) {
throw new Error(`Coundn't find param ${paramKey}. It should be declared in a route path.`)
}
if (numeric && isNaN(Number(paramValue))) {
throw new Error(`Param ${paramKey} is not number.`, { cause: { paramValue } })
}
return paramValue as N extends true ? number : string
}
export default useParam When the error is thrown I catch it with I use it to validate only numbers, but I guess you could spread this to Date also. |
Is there a way to make url generation for path parameters such as
/blog/:postId
accept only numbers (provided thatpostId
should be a number) via typescript? Writing this kind of logic manually is super repetitive and I believe it should be possible to simplify it with code generation.The text was updated successfully, but these errors were encountered: