T
TanStack2y ago
deep-jade

how do I get the current path fully typed?

I have a LocaleSwitcher component which is responsible to change the language of my app. it basically convert something like app.com/en/... to app.com/de/... i'm getting this error because I pass a simple string to the navigate.to:
Argument of type '{ to: string; }' is not assignable to parameter of type 'NavigateOptions<Route<any, "/", "/", string, "__root__", RootSearchSchema,
...
Argument of type '{ to: string; }' is not assignable to parameter of type 'NavigateOptions<Route<any, "/", "/", string, "__root__", RootSearchSchema,
...
I've tried using the router.state.location.pathname but it's type is this: (property) ParsedLocation<Partial<{}>>.pathname: string
No description
No description
No description
5 Replies
deep-jade
deep-jadeOP2y ago
for now using a never to ignore the error:
No description
national-gold
national-gold2y ago
So do all of your Routes have this $lang path parameter? Maybe then getting the location from useRouterState may help in getting a strictly typed output.
const location = useRouterState({ select: (s) => s.location })
const location = useRouterState({ select: (s) => s.location })
deep-jade
deep-jadeOP2y ago
@Sean Cassiere this is basically the component i'm trying to build, it's a language switcher that is available everywhere in the app.
export default function LocaleSwitcher({
buttonClassName,
// navigateOptions,
hideCurrentLanguageName = false
}: LocaleSwitcherProps) {
const locale = useLocale();
const navigate = useNavigate();
const location = useRouterState({ select: (s) => s.location });

console.info({ location });

const redirectTo = (lang: string) => {
// type error - can't figure out how to type correctly
navigate({ to: location.pathname });

// navigateOptions.params.lang = lang;

// navigate({ to: navigateOptions.to });
// navigateOptions.
// console.info({ aaa: { ...navigateOptions, params: { ...navigateOptions, lang } } });
// navigate({ ...navigateOptions, params: { ...navigateOptions, lang } });
// navigate({ to: '/$lang/$entityId/menu', params: { lang, entityId: '317aa97e-3b15-49f0-80be-866bf9562bfd' } });
};

const items = [
<DropdownItem
onClick={() => redirectTo('en')}
key="english"
>
English
</DropdownItem>,
<DropdownItem
onClick={() => redirectTo('es')}
key="Espanol"
>
Español
</DropdownItem>,
];

return (
<Dropdown>
<DropdownTrigger>
<Button
isIconOnly={hideCurrentLanguageName}
variant="light"
className={cn('flex ps-0 justify-between', buttonClassName)}
>
<Avatar size="md" alt={locale} src={LocaleFlags[locale]} />
{!hideCurrentLanguageName && LocaleNames[locale]}
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Static Actions">{items}</DropdownMenu>
</Dropdown>
);
}
export default function LocaleSwitcher({
buttonClassName,
// navigateOptions,
hideCurrentLanguageName = false
}: LocaleSwitcherProps) {
const locale = useLocale();
const navigate = useNavigate();
const location = useRouterState({ select: (s) => s.location });

console.info({ location });

const redirectTo = (lang: string) => {
// type error - can't figure out how to type correctly
navigate({ to: location.pathname });

// navigateOptions.params.lang = lang;

// navigate({ to: navigateOptions.to });
// navigateOptions.
// console.info({ aaa: { ...navigateOptions, params: { ...navigateOptions, lang } } });
// navigate({ ...navigateOptions, params: { ...navigateOptions, lang } });
// navigate({ to: '/$lang/$entityId/menu', params: { lang, entityId: '317aa97e-3b15-49f0-80be-866bf9562bfd' } });
};

const items = [
<DropdownItem
onClick={() => redirectTo('en')}
key="english"
>
English
</DropdownItem>,
<DropdownItem
onClick={() => redirectTo('es')}
key="Espanol"
>
Español
</DropdownItem>,
];

return (
<Dropdown>
<DropdownTrigger>
<Button
isIconOnly={hideCurrentLanguageName}
variant="light"
className={cn('flex ps-0 justify-between', buttonClassName)}
>
<Avatar size="md" alt={locale} src={LocaleFlags[locale]} />
{!hideCurrentLanguageName && LocaleNames[locale]}
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Static Actions">{items}</DropdownMenu>
</Dropdown>
);
}
it should be able to go from: http://localhost:5173/#/en/317aa97e-3b15-49f0-80be-866bf9562bfd/menu to: http://localhost:5173/#/es/317aa97e-3b15-49f0-80be-866bf9562bfd/menu
national-gold
national-gold2y ago
Sorry, been out for a bit. Would you happen to have a simplified version of this I could play around with? Like in a Stackblitz or something?
national-gold
national-gold2y ago
I took a stab at it and came up with this. https://stackblitz.com/edit/github-bh7q2o?file=src%2Froutes%2F-components%2Flanguage-switcher.tsx I'm any-casting the to prop since I'd always know where this component is being called from.
Sean Cassiere
StackBlitz
router path param lang switcher - StackBlitz
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz

Did you find this page helpful?