Skip to content

Infer required params from path template #138

@mdarens

Description

@mdarens

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:
image

Screenshot of TypeScript catching a spelling mistake:
image

Thanks so much for your time! I love this library.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions