There is a Link component in @tanstack/react-router. I want to nest (wrap) this component into my own component(s).
How can I do this and keep the type-safety which it provides?
This is example of the structure
interface ContainerProps {
to: // What type should be here?
param: // What type should be here?
}
function Container (props: ContainerProps) {
return <WrappedLink to={props.to} params={props.params} />
}
interface WrapperProps {
// What should be here?
}
function WrappedLink(props: PropsWithChildren<WrapperProps>) {
return <Link {...props}>{props.children}</Link>
}
This is how it should be used
function Page() {
const params = page1.useParams()
return <Container to={page2.to} params={params.foo} /> // NOTE: TypeScript should autosuggest what values are available
}
This is component hierarchy for simplicity
Page (pass `to` & `params`)
- Container (pass `to` & `params`)
- Wrapper (pass `to` & `params`)
- Link
P.S. I checked other posts here on StackOverflow, but didn't find a solution :(
Outdated. Check the latest answer down below.
This is an example of how it can be used with "@tanstack/react-router": "^1.2.2"
import { AnyRoute, Link, LinkProps, RegisteredRouter, RoutePaths } from "@tanstack/react-router";
import { ReactNode } from "react";
export function CustomLink<
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
TFrom extends RoutePaths<TRouteTree> | string = string,
TTo extends string = '',
TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''
>({
linkProps,
children,
}: {
linkProps: LinkProps<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & React.RefAttributes<HTMLAnchorElement>
children: ReactNode
}) {
return <Link {...linkProps}>{children}</Link>
}
Then, it can be used like
function Main() {
return (
<CustomLink linkProps={{ to: "/$param", params: { foo: "foo" } }}>
Click here
</CustomLink>
)
}
P.S. Honestly, I don't know what all these types mean, but it was suggested on the React-Router Discord channel.
Update April 26, 2024:
By the time I write this update, there is an option to use the createLink
utility provided by the @tanstack/react-router@^1.28.1
development team. It's not currently available in the documentation, but you can follow the official Discord channel where this topic was proposed and discussed
Here is the little example on how to use the createLink
util.
// 1. Import from the package
import { createLink } from "@tanstack/react-router"
// 2. Create your component
const Component = (props) => <div>{props.title}</div>
// 3. Use the util to create a new Link component
const MyLink = createLink(Component)
// 4. Use the created MyLink component with correct types inference
<MyLink to="/$userId/settings" params={{ userId: "123" }} />