Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types(#42003): better typing for next/link #42117

Merged
merged 11 commits into from Nov 14, 2022
21 changes: 9 additions & 12 deletions packages/next/client/link.tsx
Expand Up @@ -83,21 +83,18 @@ type InternalLinkProps = {
* @see https://github.com/vercel/next.js/commit/489e65ed98544e69b0afd7e0cfc3f9f6c2b803b7
*/
legacyBehavior?: boolean
// e: any because as it would otherwise overlap with existing types
/**
* Optional event handler for when the mouse pointer is moved onto Link
*/
onMouseEnter?: (e: any) => void
// e: any because as it would otherwise overlap with existing types
onMouseEnter?: React.MouseEventHandler<HTMLAnchorElement>
/**
* Optional event handler for when Link is touched.
*/
onTouchStart?: (e: any) => void
// e: any because as it would otherwise overlap with existing types
onTouchStart?: React.TouchEventHandler<HTMLAnchorElement>
/**
* Optional event handler for when Link is clicked.
*/
onClick?: (e: any) => void
onClick?: React.MouseEventHandler<HTMLAnchorElement>
}

// TODO-APP: Include the full set of Anchor props
Expand Down Expand Up @@ -520,14 +517,14 @@ const Link = React.forwardRef<HTMLAnchorElement, LinkPropsReal>(
])

const childProps: {
onTouchStart: React.TouchEventHandler
onMouseEnter: React.MouseEventHandler
onClick: React.MouseEventHandler
onTouchStart: React.TouchEventHandler<HTMLAnchorElement>
onMouseEnter: React.MouseEventHandler<HTMLAnchorElement>
onClick: React.MouseEventHandler<HTMLAnchorElement>
href?: string
ref?: any
} = {
ref: setRef,
onClick: (e: React.MouseEvent) => {
onClick(e) {
if (process.env.NODE_ENV !== 'production') {
if (!e) {
throw new Error(
Expand Down Expand Up @@ -569,7 +566,7 @@ const Link = React.forwardRef<HTMLAnchorElement, LinkPropsReal>(
prefetchEnabled
)
},
onMouseEnter: (e: React.MouseEvent) => {
onMouseEnter(e) {
if (!legacyBehavior && typeof onMouseEnterProp === 'function') {
onMouseEnterProp(e)
}
Expand Down Expand Up @@ -597,7 +594,7 @@ const Link = React.forwardRef<HTMLAnchorElement, LinkPropsReal>(
bypassPrefetchedCheck: true,
})
},
onTouchStart: (e: React.TouchEvent<HTMLAnchorElement>) => {
onTouchStart(e) {
if (!legacyBehavior && typeof onTouchStartProp === 'function') {
onTouchStartProp(e)
}
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/new-link-behavior/typescript/pages/index.tsx
Expand Up @@ -8,7 +8,7 @@ import {
import NextLink, { LinkProps } from 'next/link'

type NativeButtonProps = Omit<
HTMLProps<HTMLButtonElement>,
HTMLProps<HTMLAnchorElement>,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With new link behavior, the <Link /> will always render a HTMLAnchorElement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With new link behavior, the <Link /> will always render a HTMLAnchorElement.

'type' | 'prefix' | 'size' | 'width' | 'shape' | 'onClick'
>

Expand Down
18 changes: 17 additions & 1 deletion test/production/typescript-basic/app/pages/index.tsx
Expand Up @@ -12,7 +12,23 @@ export default function Page() {
return (
<>
<p>hello world</p>
<Link href="/another">to /another</Link>
<Link
href="/another"
onClick={(e) => {
console.log(e.currentTarget)
}}
>
to /another
</Link>
<Link
href="/another"
onClick={(e) => {
/** @ts-expect-error - foo does not exist on React.MouseEvent */
console.log(e.foo)
}}
>
to /another
</Link>
</>
)
}