menu
Channels
Team

Issue typing usage of Link with TypeScript

November 30, 2018 at 10:33am

Issue typing usage of Link with TypeScript

November 30, 2018 at 10:33am

Hi, I'm having some issues with typing usage of Link with TypeScript. I'm pretty new to TypeScript so I'm probably doing something wrong, but I really can't figure out if it's an actual problem with the type definitions of reach router or not.

I've created a repo on github to reproduce the issue:

https://github.com/artisologic/reach-router-ts-issue

Any help would be highly appreciated!

Thanks!


December 1, 2018 at 11:02pm

Hi,

I don't understand why you wrap the `Link` around the `MyLink` function since all you are doing is returning it without adding any custom props :)

But let's say you wanted to pass some additional props, you could do it like this:

type Props = {
label: string
}
function MyLink(props: Props & LinkProps<{}>) {
return <Link>{props.label}</Link>
}

Later on call site:

<MyLink label="ok" to="/"/>
Edited
  • reply
  • like

Hi

, thanks for your reply. Yes the example is contrived, that's just to synthesise the issue I'm having. In reality it's rather a NavLink implementation which adds a className if the link is active (current route). Your example makes sense to me, but it doesn't solve the issue I'm having. The compiler still complains about the same thing exactly. Did you try on your side?

  • reply
  • like

I see, you should check the docs here: https://reach.tech/router/example/active-links

But for the gist of it:

type Props = {
label: string
activeClassName: string
}
function MyLink(props: Props & LinkProps<{}>) {
return (
<Link
getProps={linkProps => ({
className: linkProps.isCurrent && props.activeClassName,
})}
>
{props.label}
</Link>
)
}

later on call site:

<MyLink activeClassName="bar" label="ok" to="/" />
Edited
  • reply
  • like

April 30, 2019 at 8:44am

Hi, I don't know how to deal with custom link in type script. When I write this

const NavLink: React.FC<LinkProps<{}>> = (props: LinkProps<{}>) => (
<Link
{...props}
getProps={({ isCurrent }) => {
// the object returned here is passed to the
// anchor element's props
return {
style: {
color: isCurrent ? 'red' : 'blue'
}
};
}}
/>
);
export default NavLink;

I have the following error

Type '{ getProps: (linkProps: LinkGetProps) => { style: { color: string; }; }; to?: string | undefined; replace?: boolean | undefined; state?: {} | undefined; ref?: string | ((instance: HTMLAnchorElement | null) => void) | RefObject<...> | null | undefined; ... 260 more ...; onTransitionEndCapture?: ((event: TransitionEve...' is not assignable to type 'IntrinsicClassAttributes<Link<{}>>'.
Types of property 'ref' are incompatible.
Type 'string | ((instance: HTMLAnchorElement | null) => void) | RefObject<HTMLAnchorElement> | null | undefined' is not assignable to type 'string | ((instance: Link<{}> | null) => void) | RefObject<Link<{}>> | null | undefined'.
Type '(instance: HTMLAnchorElement | null) => void' is not assignable to type 'string | ((instance: Link<{}> | null) => void) | RefObject<Link<{}>> | null | undefined'.
Type '(instance: HTMLAnchorElement | null) => void' is not assignable to type '(instance: Link<{}> | null) => void'.
Types of parameters 'instance' and 'instance' are incompatible.
Type 'Link<{}> | null' is not assignable to type 'HTMLAnchorElement | null'.
Type 'Link<{}>' is missing the following properties from type 'HTMLAnchorElement': charset, coords, download, hreflang, and 262 more.
Edited
  • reply
  • like

The only way I found to make it run is to use any ....

const NavLink = (props: any) => (
<Link
{...props}
getProps={({ isCurrent }) => {
// the object returned here is passed to the
// anchor element's props
return {
style: {
color: isCurrent ? 'red' : 'blue'
}
};
}}
/>
);
export default NavLink;
Edited
  • reply
  • like

April 30, 2019 at 7:44pm

Hello, I made a codesandbox, you can take a look, maybe it will help you :)

  • reply
  • like

May 2, 2019 at 7:40am

Hi

, thanks for your answer and your example. I am a bit disappointed that I cannot pass directly the props without naming them (like in JS :) )

  • reply
  • like