T
TanStack7mo ago
inland-turquoise

Trying to use ValidateLinkOptions in a dynamic menu structure is proving difficult - any tips?

I'm trying to create a dynamic menu in an array like this:
{
label: __("Events"),
icon: IconEvents,
items: [
{
label: __("Events"),
can: Permission.ViewEvents,
linkProps: {
to: "/$orgSid/events",
params: {
orgSid: org.sid,
},
},
},
],
},
]
{
label: __("Events"),
icon: IconEvents,
items: [
{
label: __("Events"),
can: Permission.ViewEvents,
linkProps: {
to: "/$orgSid/events",
params: {
orgSid: org.sid,
},
},
},
],
},
]
I want to add type assertions on linkProp and have tried all sorts using ValidateLinkOptions:
export interface MenuLink<
TRouter extends RegisteredRouter = RegisteredRouter,
TOptions = unknown,
> extends BaseLink {
linkProps?: ValidateLinkOptions<TRouter, TOptions>;
onClick?: () => void;
icon?: Icon;
items?: MenuLink[];
}
export interface MenuLink<
TRouter extends RegisteredRouter = RegisteredRouter,
TOptions = unknown,
> extends BaseLink {
linkProps?: ValidateLinkOptions<TRouter, TOptions>;
onClick?: () => void;
icon?: Icon;
items?: MenuLink[];
}
I've also tried non-recusrive versions, simpler versions etc etc. I can't get the typing to work. I get the "to" property working in some cases, but the param then often fails with an error like:
Object literal may only specify known properties, and orgSid does not exist in type
ParamsReducerFn<RouterCore<Route<any, "/", "/", string, "__root__", undefined, {}, MyRouterContext, AnyContext, AnyContext, {}, undefined, RootRouteChildren, FileRouteTypes>, "never", true, RouterHistory, Record<...>>, "PATH", string, undefined>
Object literal may only specify known properties, and orgSid does not exist in type
ParamsReducerFn<RouterCore<Route<any, "/", "/", string, "__root__", undefined, {}, MyRouterContext, AnyContext, AnyContext, {}, undefined, RootRouteChildren, FileRouteTypes>, "never", true, RouterHistory, Record<...>>, "PATH", string, undefined>
Any ideas?
4 Replies
genetic-orange
genetic-orange7mo ago
Link Options | TanStack Router React Docs
You may want to reuse options that are intended to be passed to Link, redirect or navigate. In which case you may decide an object literal is a good way to represent options passed to Link. tsx const...
inland-turquoise
inland-turquoiseOP7mo ago
If I wrap the linkProps in that function, then inside my menu components I still need to type the menu items, and the submenu items which is wher it breaks down e.g. inside <CollapsibleNavItem item={link} /> which contains {item.items?.map((subItem) => ( <Link {...linkProps} /> <- which is where it breaks
genetic-orange
genetic-orange7mo ago
probably best is to provide a complete minimal example cc @Chris Horobin
sensitive-blue
sensitive-blue7mo ago
I've been using type LinkOptions['to']. It doesn't validate params, but it at least matches pathnames.

Did you find this page helpful?