useMatches and Typescript #9534
-
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
Facing issues typing this as well? Is there a good workaround for this? |
Beta Was this translation helpful? Give feedback.
-
Thank you for your comment. I have not found any other solution than to completely rethink my component. I think the basis of my problem is a wrong imported type. But the documentation for Typescript is so poor... I'm still looking for the correct solution. |
Beta Was this translation helpful? Give feedback.
-
Try something like this: type RouteWithHandle<Handle extends string, Value> = {
id: string;
pathname: string;
params: Params<string>;
data: unknown;
handle: Record<Handle, Value>;
};
function isRecordWithKey<T extends string>(
value: unknown,
key: T,
): value is Record<T, unknown> {
return !!value && typeof value === "object" && key in value;
}
function hasHandle<Handle extends string, Value>(
handle: Handle,
valuePredicate?: (v: unknown) => v is Value,
) {
return (
route:
| {
handle: unknown;
}
| RouteWithHandle<Handle, Value>,
): route is RouteWithHandle<Handle, Value> => {
return (
!!route.handle &&
isRecordWithKey(route.handle, handle) &&
(!valuePredicate ||
(handle in route.handle && valuePredicate(route.handle[handle])))
);
};
}
function isString(value: unknown): value is string {
return typeof value === 'string';
}
function MyComponent() {
const matches = useMatches();
const routesInfos = matches.filter(hasHandle("infos", isString)).map(match => match.handle.infos);
} |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
useMatches
does not returnRouteObject[]
, but since they share some properties TS is allowing you to incorrectly define the type that way. A "match" in this case is a mixtures of a matched route and the result of the routesloader
function, so just remove: RouteObject[]
and TS should be happy: