I’m trying to create a generic return type for this function, but I’m struggling hard. I’ve managed to get the keys but only if I changed QueryParam
to QueryParam<T extends string>
and use the generic type parameter T
for name
, but the values were all type of never
.
So like this:
type QueryParam<T extends string> = {
name: T
type: 'string' | 'number' | 'boolean'
isArray?: boolean
transform?: (value: string | string[] | undefined) => unknown
}
This is how the original code looks like:
type QueryParam = {
name: string
type: 'string' | 'number' | 'boolean'
isArray?: boolean
transform?: (value: string | string[] | undefined) => unknown
}
const extractQueryParams = (query: Record<string, string | string[] | undefined>, params: QueryParam[]) => {
const queryParams: Record<string, unknown> = {}
for (const param of params) {
const key = param.name
if (!query[key]) continue
const type = param.type
const currentParam = query[key] as string | string[]
if ((!param.isArray && Array.isArray(currentParam)) || (param.isArray && !Array.isArray(currentParam))) {
if (!param.transform) continue
queryParams[key] = param.transform(currentParam)
continue
}
const parse = (x: string) => (type === 'number' ? Number(x) : type === 'boolean' ? Boolean(x) : x)
if (!param.isArray && !Array.isArray(currentParam)) {
queryParams[key] = parse(currentParam)
continue
}
if (param.isArray && Array.isArray(currentParam)) {
queryParams[key] = (currentParam as string[]).map(x => parse(x))
continue
}
}
return queryParams
}
This is how I call it:
const params = extractQueryParams(router.query, [{ name: 'page', type: 'number' }])
This is what I’d like to achive for the type of variable params
with this input:
{ page: number }