T
TanStack4mo ago
correct-apricot

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
optimistic-gold
optimistic-gold4mo 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...
correct-apricot
correct-apricotOP4mo 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
optimistic-gold
optimistic-gold4mo ago
probably best is to provide a complete minimal example cc @Chris Horobin
rising-crimson
rising-crimson4mo 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?