Skip to content

Instantly share code, notes, and snippets.

@tomhicks
Created July 24, 2020 11:09
Show Gist options
  • Save tomhicks/56b6a159ab5e727e5f43353172a49b6d to your computer and use it in GitHub Desktop.
Save tomhicks/56b6a159ab5e727e5f43353172a49b6d to your computer and use it in GitHub Desktop.
Strongly-typed NextJS internal links
const glob = require("glob")
const fs = require("fs")
const prettier = require("prettier")
const basePath = "src/app/pages"
glob(`${basePath}/**/*.{tsx,ts}`, undefined, (err, files) => {
const pageFiles = files
.map(f =>
f
.replace(basePath, "")
.replace(/\.\w+$/, "")
.replace(/\/index$/, ""),
)
.filter(f => !f.startsWith("/_"))
.map(file => {
const paramNames = (file.match(/\[\w+\]/g) || []).map(pathSegment =>
pathSegment.replace(/[\[\]]/g, ""),
)
return {
routeName: file,
routeParams: paramNames,
}
})
const allTypes = pageFiles.map(typeTemplate)
fs.writeFileSync(
"src/app/types/routes.ts",
prettier.format(
`
export type InternalRoutes = | ${allTypes.join("\n| ")}
`,
{
semi: false,
parser: "typescript",
},
),
)
})
const typeTemplate = ({routeName, routeParams}) => `{
routeName: "${routeName}";
routeParams${routeParams.length ? "" : "?"}: {
${routeParams.map(param => `${param}: string`).join(";\n ")}
}
}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment