Skip to content

Instantly share code, notes, and snippets.

@prichodko
Created May 28, 2024 11:59
Show Gist options
  • Save prichodko/9d4462dabf3d7c43e21a61f382fcaf77 to your computer and use it in GitHub Desktop.
Save prichodko/9d4462dabf3d7c43e21a61f382fcaf77 to your computer and use it in GitHub Desktop.
Next.js – type-safe useParams
import { useParams as useParamsBase } from 'next/navigation'
type DefaultParams = {
[key: string]: string | string[]
}
type Params = {
space: string
project: string
content: string
asset: string
}
class ParamsMissingError extends Error {
constructor() {
super(`'params' not found props`)
}
}
class ParamsKeyNotFoundError extends Error {
constructor(key: string, params: string) {
super(`'${key}' does not exist in params: ${params}.`)
}
}
function createProxy<T extends DefaultParams>(target: T): T {
return new Proxy(target, {
get(target, prop: string) {
if (target[prop] === undefined) {
throw new ParamsKeyNotFoundError(String(prop), JSON.stringify(target))
}
return target[prop as keyof T]
},
})
}
export function params<T extends Params>(props: Record<string, any>): Params {
if ('params' in props === false) {
throw new ParamsMissingError()
}
return createProxy<T>(props.params)
}
export function useParams<T extends Params>(): T {
const params = useParamsBase<any>()
return createProxy<T>(params)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment