Gatsby: GatsbyLinkProps typescript type not working for custom <Link /> component

Created on 16 Aug 2019  路  6Comments  路  Source: gatsbyjs/gatsby

Description

I'm trying to extend a <Link /> component in my Typescript project. This is a simplified example:

const CustomLink: React.FC<GatsbyLinkProps<any>> = props => <Link {...props} />

I'm getting the error:

Type '{ activeClassName?: string; activeStyle?: object; innerRef?: Function; onClick?: (event: MouseEvent<HTMLAnchorElement, MouseEvent>) => void; partiallyActive?: boolean; replace?: boolean; ... 263 more ...; onTransitionEndCapture?: (event: TransitionEvent<...>) => void; }' is not assignable to type 'IntrinsicClassAttributes<GatsbyLink<any>>'.
  Types of property 'ref' are incompatible.
    Type 'LegacyRef<HTMLAnchorElement>' is not assignable to type 'LegacyRef<GatsbyLink<any>>'.
      Type '(instance: HTMLAnchorElement) => void' is not assignable to type 'LegacyRef<GatsbyLink<any>>'.
        Type '(instance: HTMLAnchorElement) => void' is not assignable to type '(instance: GatsbyLink<any>) => void'.
          Types of parameters 'instance' and 'instance' are incompatible.
            Type 'GatsbyLink<any>' is missing the following properties from type 'HTMLAnchorElement': charset, coords, download, hreflang, and 260 more.ts(2322)

However, GatsbyLinkProps seems to be what the <Link /> component defines as its prop type, so this should work. Am I doing something wrong, or is this a bug with the type definitions?

Steps to reproduce

Go to https://codesandbox.io/s/gatsby-typescript-link-frt1h and open src/pages/index.tsx, or

  1. Bootstrap new Gatsby project
  2. Add gatsby-plugin-typescript to the project
  3. Try to define the following component:
const CustomLink: React.FC<GatsbyLinkProps<any>> = props => <Link {...props} />

Expected result

No compile error

Actual result

Compile error as described above

Environment

https://codesandbox.io/s/gatsby-typescript-link-frt1h

not stale reacrouter and Links

Most helpful comment

Just for future developers searching for this issue, I implemented this way:
interface CustomGatsbyLink extends Omit<GatsbyLinkProps<Record<string, unknown>>, 'ref'>

In Typescript version 4, you can't use {} as type, you have to use Record

All 6 comments

I reproduced the issue. The problem seems to be with the "ref" property. Gatsby Link is using @reach/router's link internally. Gatsby Link is exported with forwardRef, which gives you access to the ref as a property, and it forwards it to @reach/router's Link. A workaround I came up with is to just exclude the "ref" property from GatsbyLinkProps. It is not ideal, but you can still use "innerRef", which will properly be passed to @reach/router to handle.

This is how you would make your custom component:

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
const CustomLink: React.FC<Omit<GatsbyLinkProps<{}>, 'ref'>> = props => <Link {...props} />

Keep in mind that this is just a workaround until the issue can be addressed properly.

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

I'm also having that issue. I was trying to infer type of Link's props but it doesn't work either

type NavLinkProps = Link extends React.Component<infer P> ? P : never;

I could make a PR on Gatsby typings, what do you think?
I could either Omit the ref as you did, or override the ref key,
maybe with ref: LegacyRef<HTMLAnchorElement>
Any insight?

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

Just for future developers searching for this issue, I implemented this way:
interface CustomGatsbyLink extends Omit<GatsbyLinkProps<Record<string, unknown>>, 'ref'>

In Typescript version 4, you can't use {} as type, you have to use Record

Was this page helpful?
0 / 5 - 0 ratings

Related issues

3CordGuy picture 3CordGuy  路  3Comments

mikestopcontinues picture mikestopcontinues  路  3Comments

andykais picture andykais  路  3Comments

brandonmp picture brandonmp  路  3Comments

benstr picture benstr  路  3Comments