NextJS 13's new Link, Typescript, and forwardRef
Answered
Mudi posted this in #help-forum
MudiOP
I'm upgrading from Next 12 to 13. I have a component which wraps next/link, and renders either a regular <a> tag or a next/link component, depending on whether it's an external or internal link.
After the upgrade I'm getting a new TS error and I'm not sure how to deal with it.
I'm getting the error on the
I am guessing the type of the ref (currently
I tried changing it to
Any ideas?
After the upgrade I'm getting a new TS error and I'm not sure how to deal with it.
import { forwardRef } from "react";
import NextLink from "next/link";
import { getLinkInfo, isLinkInfo } from "lib/link";
import type { EntryInfo, LinkInfo } from "lib/link";
/**
* A link which will render either an SPA link (`next/link`),
* or a regular anchor tag, as appropriate.
*
* This often imported as `A` rather than `Link`.
*/
export const Link = forwardRef<
HTMLAnchorElement,
{
/**
* Either a string href, an EntryInfo structure, or a LinkInfo structure.
*/
href?: string | EntryInfo | LinkInfo;
} & Omit<React.ComponentProps<"a">, "href">
>(function LinkWithRef({ href, ...props }, ref) {
if (href == null) return <a {...props} />;
let linkInfo: LinkInfo | null = null;
if (isLinkInfo(href)) linkInfo = href;
else linkInfo = getLinkInfo(href);
if (linkInfo.isLocal) {
return (
<NextLink ref={ref} href={linkInfo.href} {...props} />
);
}
return <a ref={ref} href={linkInfo.href} {...props} />;
});I'm getting the error on the
ref prop where I return <NextLink ...:Type 'string | ((instance: HTMLAnchorElement | null) => void) | RefObject<HTMLAnchorElement> | null' is not assignable to type 'Ref<HTMLAnchorElement> | undefined'.
Type 'string' is not assignable to type 'Ref<HTMLAnchorElement> | undefined'.I am guessing the type of the ref (currently
HTMLAnchorElement) needs to change to accomodate Next 13's changes, but I don't know what it needs to change to. Or maybe I need to narrow a type somewhere?I tried changing it to
HTMLAnchorElement | typeof NextLink and that leads to a much more cryptic error.Any ideas?
Answered by Mudi
Figured it out, the
& Omit<React.ComponentProps<"a">, "href"> part of my prop types was including HTMLAnchorElement's own ref prop, and that was conflicting with the forwarded one. I needed to change the omission to "href" | "ref".7 Replies
MudiOP
I'm not even sure where the string it's complaining about is coming from.
ref is of type ForwardedRef<HTMLAnchorElement>, which is ((instance: HTMLAnchorElement | null) => void) | { current: HTMLAnchorElement | null } | null and I don't see strings anywhere in thereMudiOP
Figured it out, the
& Omit<React.ComponentProps<"a">, "href"> part of my prop types was including HTMLAnchorElement's own ref prop, and that was conflicting with the forwarded one. I needed to change the omission to "href" | "ref".Answer
@Mudi I'm late but you can also type it as
React.ComponentPropsWithoutRef<"a">, but since you are already using the Omit for href it makes sense to just include ref thereOriental
the whole ref forwardref thing. WHY?!
Syntax of React and Next.js is somewhat really annoying
Please point me to good tutorials about this topic