-
Notifications
You must be signed in to change notification settings - Fork 61
Description
Is your feature request related to a problem? Please describe.
When param keys are defined in the path template, there is no static validation that they are present in the params object, which can lead to unbound path template components at runtime. The most likely case in which this occurs tends to be a casing or spelling mismatch on a path template component or params property.
Describe the solution you'd like
With the advent of template literal types in TypeScript 4.1, we can check for keys defined in the path argument and make them required in params. I've stubbed out a naïve annotation, which doesn't cover all the implemented overloads, as a proof of concept.:
type PathTemplateTokens<Rte> = Rte extends `${string}/:${infer P}/${infer Rest}`
? P | PathTemplateTokens<`/${Rest}`>
: Rte extends `${string}/:${infer P}`
? P
: never;
function urlcat<BaseUrl extends string,
PathTemplate extends string,
Params extends Record<PathTemplateTokens<PathTemplate>, string | number>
>(
baseUrl: BaseUrl,
pathTemplate: PathTemplate,
params: Params) { };
urlcat("http://example.com", "org/:orgName/user/:userId", {
foo: "bar"
}); // error! required properties missing
urlcat("http://example.com", "org/:orgName/user/:userId", {
orgname: "SprocketCo",
userId: "951d20a0-e188-4db4-a946-df426d3d9e91"
}); // error! suggests `orgName` when spelled `orgname`
urlcat("http://example.com", "org/:orgName/user/:userId", {
orgName: "SprocketCo",
userId: "951d20a0-e188-4db4-a946-df426d3d9e91"
}); // ok, everything required is there
urlcat("http://example.com", "org/:orgName/user/:userId", {
orgName: "SprocketCo",
userId: "951d20a0-e188-4db4-a946-df426d3d9e91",
sortBy: "sprocketsPerWeek"
}); // ok, extra stuff goes in the query string
Describe alternatives you've considered
N/A
Additional context
Add any other context or screenshots about the feature request here.
TypeScript Playground link to stub implementation
Screenshot of TypeScript suggesting params:
Screenshot of TypeScript catching a spelling mistake:
Thanks so much for your time! I love this library.