Repository: tatethurston/nextjs-routes
Pull request #100 (2022-11-21 01:31:31)

Link anchor props


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b89838..b200000 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
 # Changelog
 
+## 1.0.2
+
+- `Link` now [accepts anchor props](https://beta.nextjs.org/docs/api-reference/components/link):
+
+  ```tsx
+  <Link href="/dashboard" className="border-indigo-500">
+    Dashboard
+  </Link>
+  ```
+
 ## 1.0.1
 
 - Update `NextRouter` type to keep `query` and `pathname` bound in a union. This allows you to use `router` from `useRouter` as an argument to `router.push` or `router.replace`:
diff --git a/examples/intl/nextjs-routes.d.ts b/examples/intl/nextjs-routes.d.ts
index 7917045..95b8aea 100644
--- a/examples/intl/nextjs-routes.d.ts
+++ b/examples/intl/nextjs-routes.d.ts
@@ -34,14 +34,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: Locale | false;
   }
@@ -81,7 +87,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: Locale | false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -133,7 +139,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
diff --git a/examples/typescript/types/nextjs-routes.d.ts b/examples/typescript/types/nextjs-routes.d.ts
index b17959c..d185e67 100644
--- a/examples/typescript/types/nextjs-routes.d.ts
+++ b/examples/typescript/types/nextjs-routes.d.ts
@@ -33,14 +33,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -80,7 +86,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -128,7 +134,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
diff --git a/public.package.json b/public.package.json
index 3caf333..23e93e8 100644
--- a/public.package.json
+++ b/public.package.json
@@ -1,6 +1,6 @@
 {
   "name": "nextjs-routes",
-  "version": "1.0.1",
+  "version": "1.0.2",
   "description": "Type safe routing for Next.js",
   "license": "MIT",
   "author": "Tate <tatethurston@gmail.com>",
diff --git a/src/core.ts b/src/core.ts
index 703ba1e..0104bb6 100644
--- a/src/core.ts
+++ b/src/core.ts
@@ -128,14 +128,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: ${!i18n.locales.length ? "false" : `Locale | false`};
   }
@@ -175,7 +181,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: ${!i18n.locales.length ? "false" : `Locale | false`};
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -229,7 +235,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }


Test patch:
diff --git a/e2e/nextjs-routes.d.ts b/e2e/nextjs-routes.d.ts
index 9e0ea48..43b4c1c 100644
--- a/e2e/nextjs-routes.d.ts
+++ b/e2e/nextjs-routes.d.ts
@@ -32,14 +32,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -79,7 +85,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -127,7 +133,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
diff --git a/e2e/package-lock.json b/e2e/package-lock.json
index b6596a9..c9ef50f 100644
--- a/e2e/package-lock.json
+++ b/e2e/package-lock.json
@@ -20,7 +20,7 @@
     },
     "../dist": {
       "name": "nextjs-routes",
-      "version": "1.0.0",
+      "version": "1.0.2",
       "dev": true,
       "license": "MIT",
       "dependencies": {
diff --git a/e2e/typetest.tsx b/e2e/typetest.tsx
index 21d1852..31d5926 100644
--- a/e2e/typetest.tsx
+++ b/e2e/typetest.tsx
@@ -57,6 +57,8 @@ function expectType<T>(_value: T) {}
 />;
 // @ts-expect-error replace typo
 <Link href={{ query: {} }} replacey />;
+// anchor props https://beta.nextjs.org/docs/api-reference/components/link#props
+<Link href={{ query: {} }} className="foo" />;
 
 // LinkProps
 
diff --git a/src/__snapshots__/core.test.ts.snap b/src/__snapshots__/core.test.ts.snap
index 16b2630..0b28454 100644
--- a/src/__snapshots__/core.test.ts.snap
+++ b/src/__snapshots__/core.test.ts.snap
@@ -37,14 +37,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -84,7 +90,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -132,7 +138,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -180,14 +186,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: Locale | false;
   }
@@ -227,7 +239,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: Locale | false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -292,7 +304,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -337,14 +349,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -384,7 +402,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -432,7 +450,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -479,14 +497,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -526,7 +550,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -574,7 +598,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -619,14 +643,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -666,7 +696,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -714,7 +744,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -759,14 +789,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -806,7 +842,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -854,7 +890,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -899,14 +935,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -946,7 +988,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -994,7 +1036,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -1039,14 +1081,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -1086,7 +1134,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -1134,7 +1182,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }
@@ -1196,14 +1244,20 @@ declare module "nextjs-routes" {
 declare module "next/link" {
   import type { Route } from "nextjs-routes";
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
-  import type { PropsWithChildren, MouseEventHandler } from "react";
+  import type {
+    AnchorHTMLAttributes,
+    DetailedReactHTMLElement,
+    PropsWithChildren,
+    MouseEventHandler,
+  } from "react";
   export * from "next/dist/client/link";
 
   type Query = { query?: { [key: string]: string | string[] | undefined } };
   type StaticRoute = Exclude<Route, { query: any }>["pathname"];
 
   export interface LinkProps<Href extends Route | Query = Route | Query>
-    extends Omit<NextLinkProps, "href" | "locale"> {
+    extends Omit<NextLinkProps, "href" | "locale">,
+      AnchorHTMLAttributes<HTMLAnchorElement> {
     href: Href;
     locale?: false;
   }
@@ -1243,7 +1297,7 @@ declare module "next/router" {
 
   interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
     locale?: false;
-  };
+  }
 
   export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
     Extract<Route, { pathname: P }> &
@@ -1291,7 +1345,7 @@ declare module "next/router" {
           options?: TransitionOptions
         ): Promise<boolean>;
         route: P;
-      }
+      };
 
   export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
 }