Currently creating a file pages/[version=semver].vue and the param parser semver as:
Bug: Exclude<ParamType, unknown[]> doesn't strip null from parsed param types
Summary
When a param parser's get returns T | T[] | null, the route map type uses Exclude<ParamType, unknown[]> to narrow array variants for non-repeatable params. This correctly removes T[] but leaves null, resulting in T | null instead of just T for required params.
Reproduction
- Define a param parser that returns a union including
null:
import { defineParamParser } from 'vue-router/experimental'
interface MyType {
value: string
}
export const parser = defineParamParser({
get: (value): MyType | MyType[] | null => {
if (!value) return null
return Array.isArray(value) ? value.map((v) => ({ value: v })) : { value }
},
set: (value: MyType | null): string | null => (value ? value.value : null),
})
-
Use this parser in a route (e.g. via definePage or route config) for a required path param like /pkg/:version.
-
In the page component, access route.params.version - it is typed as MyType | null instead of MyType.
Expected
route.params.version should be MyType since it's a required path param. null should be excluded along with the array variant.
Actual
Type is MyType | null. Components need unnecessary null guards.
Root cause
Exclude<MyType | MyType[] | null, unknown[]> removes MyType[] (since it extends unknown[]) but keeps null (since null does not extend unknown[]).
Workaround
Avoid returning null from the parser's get function. Use miss() instead to signal missing/invalid values:
get: (value): MyType | MyType[] => {
if (!value) return miss('Missing value')
// ...
}
Currently creating a file
pages/[version=semver].vueand the param parser semver as:Bug:
Exclude<ParamType, unknown[]>doesn't stripnullfrom parsed param typesSummary
When a param parser's
getreturnsT | T[] | null, the route map type usesExclude<ParamType, unknown[]>to narrow array variants for non-repeatable params. This correctly removesT[]but leavesnull, resulting inT | nullinstead of justTfor required params.Reproduction
null:Use this parser in a route (e.g. via
definePageor route config) for a required path param like/pkg/:version.In the page component, access
route.params.version- it is typed asMyType | nullinstead ofMyType.Expected
route.params.versionshould beMyTypesince it's a required path param.nullshould be excluded along with the array variant.Actual
Type is
MyType | null. Components need unnecessary null guards.Root cause
Exclude<MyType | MyType[] | null, unknown[]>removesMyType[](since it extendsunknown[]) but keepsnull(sincenulldoes not extendunknown[]).Workaround
Avoid returning
nullfrom the parser'sgetfunction. Usemiss()instead to signal missing/invalid values: