Lets say I have a discriminated union like so:
type Route = HomeRoute | ProfileRoute | BlogRoute;
type HomeRoute = {
route: '/home'
}
type ProfileRoute = {
route: '/profile/:userId',
params: {
userId: string;
}
}
type BlogRoute = {
route: '/blog/:teamId',
params: {
teamId: string;
}
}
And I have a function which operates on Route
objects, with some optional logic if they have params:
function processRoute(route: Route) {
if ('params' in route) {
const { params } = route; // <-- this errors
}
}
There doesn't seem to be a way (that I can see) to check for params
without adding an any
annotation...
function paramsInRoute(route: any): route is { params: {[key: string]: string} } {
return ('params' in route);
}
function processRoute(route: Route) {
if ('params' in route) {
const { params } = route; // <-- this errors
}
if (paramsInRoute(route)) {
const { params } = route; // <-- this typechecks
}
}
Is there a way to do the above without casting to any (in the parameter of paramsInRoute
)?
I, personally, would be happy using the type guard you have:
since TypeScript certainly narrows a passed-in
Route
object toProfileRoute
|BlogRoute
But if you're worried about someone doing this:
then you can do this:
which does the same narrowing but prevents the erroneous call:
Hope that helps; good luck!