Reflect correct type of @reach/router Link: (#43556)

Link.props.ref is actually a React.Ref<HTMLAnchorElement>. Link is
defined in terms of react's forwardRef() function, which returns a
ForwardRefExoticComponent. @reach/router actually forwards an
HTMLAnchorElement.

Without this fix, Link is a component, and "ref" is assumed to be a
React.Ref<Link>. But Link actually forwards "ref" to an <a> element
it returns.
This commit is contained in:
Eyas
2020-04-03 17:05:22 -07:00
committed by GitHub
parent 16d1f63777
commit 13ff340e33
2 changed files with 19 additions and 1 deletions
+8 -1
View File
@@ -69,7 +69,14 @@ export interface LinkGetProps {
location: WindowLocation;
}
export class Link<TState> extends React.Component<LinkProps<TState>> {}
export function Link<TState>(
// TODO: Define this as ...params: Parameters<Link<TState>> when only TypeScript >= 3.1 support is needed.
props: React.PropsWithoutRef<LinkProps<TState>> & React.RefAttributes<HTMLAnchorElement>,
): ReturnType<Link<TState>>;
export interface Link<TState>
extends React.ForwardRefExoticComponent<
React.PropsWithoutRef<LinkProps<TState>> & React.RefAttributes<HTMLAnchorElement>
> {}
export interface RedirectProps<TState> {
from?: string;
@@ -59,6 +59,17 @@ const handleRef = (el: HTMLAnchorElement) => {
};
render(<Link innerRef={handleRef} to="./foo"></Link>, document.getElementById('app-root'));
render(<Link ref={handleRef} to="./foo"></Link>, document.getElementById('app-root'));
const refObject: React.RefObject<HTMLAnchorElement> = { current: null };
render(<Link innerRef={refObject} to="./foo"></Link>, document.getElementById('app-root'));
render(<Link ref={refObject} to="./foo"></Link>, document.getElementById('app-root'));
// Link can be used as a generic.
// TODO: When TS >= 3.1 is supported, use more modern syntax:
// <Link<number> state={5} to="./foo"></Link>
React.createElement(Link as Link<number>, {
state: 5 /* Cast is a test-only fix for TS 3.1. Remove when TS >= 3.2 is supported. */ as number | undefined,
to: './foo',
ref: refObject /* Cast is a test-only fix for TS 3.1. Remove when TS >= 3.2 is supported. */ as React.Ref<HTMLAnchorElement> | undefined
});