Repository: tatethurston/nextjs-routes
Pull request #20 (2022-07-06 20:13:49)

allow passing in query without pathname
Next's `<Link>` allows us to pass in `query` without having to specify the `pathname`, assuming that we are changing query parameters on the same URL that the user is currently on. This PR updates the types to allow doing that with nextjs-routes.

codecov[bot]: # [Codecov](https://codecov.io/gh/tatethurston/nextjs-routes/pull/20?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston) Report
> Merging [#20](https://codecov.io/gh/tatethurston/nextjs-routes/pull/20?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston) (047d8fa) into [main](https://codecov.io/gh/tatethurston/nextjs-routes/commit/e88215740a35e1cdec47a9987e8536b8b64ba914?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston) (e882157) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main      #20   +/-   ##
=======================================
  Coverage   98.24%   98.24%           
=======================================
  Files           1        1           
  Lines          57       57           
  Branches       13       13           
=======================================
  Hits           56       56           
  Misses          1        1           
```


| [Impacted Files](https://codecov.io/gh/tatethurston/nextjs-routes/pull/20?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston) | Coverage Δ | |
|---|---|---|
| [src/utils.ts](https://codecov.io/gh/tatethurston/nextjs-routes/pull/20/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston#diff-c3JjL3V0aWxzLnRz) | `98.24% <ø> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tatethurston/nextjs-routes/pull/20?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tatethurston/nextjs-routes/pull/20?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston). Last update [e882157...047d8fa](https://codecov.io/gh/tatethurston/nextjs-routes/pull/20?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Tate+Thurston).

tatethurston: Thanks @sachinraja! I wasn't aware of this capability.

Do the router methods (eg `router.push`) also support this behavior? 
tatethurston: 😆 Looks like we had the same thought

Patch:
diff --git a/.gitignore b/.gitignore
index 009af54..5bcb6fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 dist
 coverage
+node_modules
diff --git a/CHANGELOG.md b/CHANGELOG.md
index afbaec5..8367858 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Changelog
 
+## 0.0.14
+
+- Allow passing in `query` without `pathname` to change current url parameters.
+- `router.query` can no longer be `undefined`.
+
 ## 0.0.13
 
 - Support search parameters. See [#17](https://github.com/tatethurston/nextjs-routes/issues/17) for more context.
diff --git a/src/utils.ts b/src/utils.ts
index a883577..efd4305 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -136,12 +136,14 @@ type QueryForPathname = {
   [K in Route as K["pathname"]]: K["query"]
 };
 
+type RouteOrQuery = Route | { query: Query }
+
 declare module "next/link" {
   import type { LinkProps as NextLinkProps } from "next/dist/client/link";
   import type { PropsWithChildren, MouseEventHandler } from "react";
 
   export interface LinkProps extends Omit<NextLinkProps, "href"> {
-    href: Route;
+    href: RouteOrQuery;
   }
 
   declare function Link(
@@ -168,10 +170,10 @@ declare module "next/router" {
   export interface NextRouter<P extends Pathname = Pathname> extends Omit<Router, "push" | "replace"> {
     pathname: P;
     route: P; 
-    query: QueryForPathname[P]
-    push(url: Route, as?: string, options?: TransitionOptions): Promise<boolean>;
+    query: Exclude<QueryForPathname[P], undefined>
+    push(url: RouteOrQuery, as?: string, options?: TransitionOptions): Promise<boolean>;
     replace(
-      url: Route,
+      url: RouteOrQuery,
       as?: string,
       options?: TransitionOptions
     ): Promise<boolean>;


Test patch:
diff --git a/src/__snapshots__/test.ts.snap b/src/__snapshots__/test.ts.snap
index b6ac2e8..187667c 100644
--- a/src/__snapshots__/test.ts.snap
+++ b/src/__snapshots__/test.ts.snap
@@ -34,12 +34,14 @@ type QueryForPathname = {
   [K in Route as K[\\"pathname\\"]]: K[\\"query\\"]
 };
 
+type RouteOrQuery = Route | { query: Query }
+
 declare module \\"next/link\\" {
   import type { LinkProps as NextLinkProps } from \\"next/dist/client/link\\";
   import type { PropsWithChildren, MouseEventHandler } from \\"react\\";
 
   export interface LinkProps extends Omit<NextLinkProps, \\"href\\"> {
-    href: Route;
+    href: RouteOrQuery;
   }
 
   declare function Link(
@@ -66,10 +68,10 @@ declare module \\"next/router\\" {
   export interface NextRouter<P extends Pathname = Pathname> extends Omit<Router, \\"push\\" | \\"replace\\"> {
     pathname: P;
     route: P; 
-    query: QueryForPathname[P]
-    push(url: Route, as?: string, options?: TransitionOptions): Promise<boolean>;
+    query: Exclude<QueryForPathname[P], undefined>
+    push(url: RouteOrQuery, as?: string, options?: TransitionOptions): Promise<boolean>;
     replace(
-      url: Route,
+      url: RouteOrQuery,
       as?: string,
       options?: TransitionOptions
     ): Promise<boolean>;