oedotme / generouted

Generated file-based routes for Vite
https://stackblitz.com/github.com/oedotme/generouted/tree/main/explorer
MIT License
1.02k stars 47 forks source link

feat: add new type that allows for typing generated parameterized paths #161

Closed Zombiefruit closed 3 months ago

Zombiefruit commented 5 months ago

Hey, loving this library and we recently migrated our application over to using it (from explicit react-router paths defined in-code). One thing I've found missing in the generated types though are template literals for parameterized path validation.

For example, we have some functions that generate paths on the fly. I'd like to make sure that they return valid paths.

function generatePathToDashboard(dashboardId: string) {
  return `/dashboards/${dashboardId}`;
}

I can't validate the above function's output currently. What I've added in this PR is a new type (name can be changed πŸ˜„) that allows for typing this sort of case. It would look like:

function generatePathToDashboard(dashboardId: string): ParameterizedPaths['/dashboards/:dashboardId'] {
  // this is now typed. Variations that don't match `/dashboards/${string}` will fail type-checking
  return `/dashboards/${dashboardId}`;
}

If you have suggestions for a better way to approach this, I'm all ears. Also, we'd probably want to change some of the variable names in the PR at the very least.

Thanks again for creating this great library!

oedotme commented 5 months ago

@Zombiefruit I can see that the generated types, specifically those share the same beginning like /dashboards/${string} would also match for /dashboards/${string}/${string}, /dashboards/oops/${string}/${string}/oops, etc:

type Path = `/dashboards/${string}`

const segment = "string"

const pass0: Path = `/dashboards/${segment}`
const pass1: Path = `/dashboards/${segment}/${segment}`  // should fail?
const pass2: Path = `/dashboards/oops/${segment}`        // should fail?
const pass3: Path = `/dashboards/${segment}/oops`        // should fail?

const fail0: Path = `/dashboardxyz/${segment}`          // this is the only case failing

I'm not sure I get the aim of the generatePathToDashboard function, but you can use the current Params type along with React Router's generatePath utility for runtime path generation.

Hope that helps.

oedotme commented 3 months ago

Closing for inactivity. Feel free to reopen when following up on this.