Skip to content

feat(next-typed-href): add requiredSearchParams option#58

Merged
amotarao merged 11 commits intomainfrom
feat/nuqs-require-search-params
Apr 30, 2026
Merged

feat(next-typed-href): add requiredSearchParams option#58
amotarao merged 11 commits intomainfrom
feat/nuqs-require-search-params

Conversation

@amotarao
Copy link
Copy Markdown
Member

@amotarao amotarao commented Apr 28, 2026

Summary

fix https://linear.app/plainbrew/issue/PC-67

  • defineTypedHrefWithNuqs を 3 重カリー化し、第 2 呼び出しで options を受け取れるようにした
  • { requiredSearchParams: true } を渡すと、nuqs パーサーが定義されたルートで searchParams オブジェクトが必須になる
  • .withDefault() なしのフィールドは必須、.withDefault() ありのフィールドは任意になる
  • DefineTypedHrefWithNuqsOptions 型を export に追加

Breaking change

既存コードは ()() に変更が必要:

// before
defineTypedHrefWithNuqs<Routes, RouteParamsMap>()({ nuqsMap })

// after
defineTypedHrefWithNuqs<Routes, RouteParamsMap>()()({ nuqsMap })

呼び出し方

// デフォルト(searchParams 任意)
const { $href } = defineTypedHrefWithNuqs<Routes, RouteParamsMap>()()({
  "/search": { q: parseAsString },
});

// requiredSearchParams: true(searchParams 必須・フィールドも型に応じて必須)
const { $href } = defineTypedHrefWithNuqs<Routes, RouteParamsMap>()(
  { requiredSearchParams: true },
)({
  "/search": {
    q: parseAsString,                    // required
    page: parseAsInteger.withDefault(1), // optional
  },
});

設計メモ

TypeScript の部分的型引数指定の制限(<Routes, RouteParamsMap> を明示すると残りの型パラメータが引数から推論されない)を、3 重カリーにすることで回避。第 2 呼び出し時点では型引数がゼロなため const Options が引数から正しく推論される。

🤖 Generated with Claude Code

…refWithNuqs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

defineTypedHrefWithNuqs がジェネリクス呼び出し → オプション呼び出し → nuqsMap の二段階カリー化を受け入れるようになり、DefineTypedHrefWithNuqsOptionsrequiredSearchParams: true を指定すると、nuqs パーサを持つルートの searchParams を型レベルで必須化するロジックが追加されました。テストと JSDoc 例も更新されています。

Changes

Cohort / File(s) Summary
Type Definitions & API
packages/next-typed-href/src/nuqs.ts
DefineTypedHrefWithNuqsOptions を追加。defineTypedHrefWithNuqs<...>() がオプション呼び出しを受け取る二段階カリー化(...>()(options)(nuqsMap) の形)へ変更。requiredSearchParams: true によって nuqs パーサを持つルートの searchParams を型的に必須化するルールを導入(withDefault() の有無で個々のパラメータの必須性を決定)。実行時の URL 生成ロジックは維持。
Tests
packages/next-typed-href/src/nuqs.test.ts
テスト呼び出しを新しい二段階パターンへ更新。requiredSearchParams: true のケースを追加し、nuqs の有無・withDefault/nullability に基づく searchParams の必須性と挙動(例:q: null がクエリを除去する)を検証。TS の負例テストも追加。
Examples
examples/.../src/lib/href.ts
examples の呼び出しをオプション呼び出しを挿入する形へ更新(defineTypedHrefWithNuqs<AppRoutes,AppRouteParamsMap>()())。エクスポート名は維持。
Release Notes / Changeset
.changeset/nuqs-required-search-params.md
Changeset を追加。API のカリー化(オプション挿入)と requiredSearchParams の型的振る舞い(nuqs フィールドの必須化規則)を記載。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • akameco
  • iromonek39

Poem

🐇
ふたつ呼んでぴょんと跳ねる型の道、
オプションひとつで鍵が変わったよ。
パーサの草原をくぐり抜けて、
テストが光る朝へ僕は走る。
新しい呼び出しで、よい跳躍を!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely summarizes the main change: adding a new requiredSearchParams option to the defineTypedHrefWithNuqs API.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/nuqs-require-search-params

Comment @coderabbitai help to get the list of available commands and usage tips.

amotarao and others added 2 commits April 28, 2026 18:02
…withDefault fields optional

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/next-typed-href/src/nuqs.ts`:
- Around line 97-103: The generic Options inference loses literal boolean
information when callers pass a variable annotated as
DefineTypedHrefWithNuqsOptions (e.g. const opts: DefineTypedHrefWithNuqsOptions
= { requireSearchParams: true }), so requireSearchParams ends up widened to
boolean; fix by adding a type-level test and doc note: add a TypeScript type
test that calls defineTypedHrefWithNuqs<Routes, RouteParamsMap>() with an
annotated variable (not an inline object) to assert that
Options["requireSearchParams"] extends true enforces required searchParams, and
update the `@example/docs` for defineTypedHrefWithNuqs (and/or the typedef
DefineTypedHrefWithNuqsOptions) to recommend using a const/satisfies assertion
when you need literal inference. Include references to the generic Options and
the returned function defineTypedHrefWithNuqs / $href in the test and docs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fe82a729-2529-4391-a57a-f44efe2838f6

📥 Commits

Reviewing files that changed from the base of the PR and between 75a2f81 and 4b8465d.

📒 Files selected for processing (2)
  • packages/next-typed-href/src/nuqs.test.ts
  • packages/next-typed-href/src/nuqs.ts

Comment thread packages/next-typed-href/src/nuqs.ts
…chParams

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@amotarao amotarao changed the title feat(next-typed-href): add requireSearchParams option feat(next-typed-href): add requiredSearchParams option Apr 28, 2026
amotarao and others added 4 commits April 28, 2026 18:07
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fault

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@amotarao amotarao requested a review from akameco April 28, 2026 09:14
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/next-typed-href/src/nuqs.ts (1)

16-16: コメント言語を統一すると保守性が上がります。

Line 16 のインラインコメントだけ日本語になっており、周辺の英語 JSDoc と混在しています。公開ライブラリとしては英語に寄せるとコントリビューター体験が安定します。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/next-typed-href/src/nuqs.ts` at line 16, Replace the lone Japanese
inline comment in nuqs.ts with an English equivalent to match the surrounding
JSDoc; specifically update the comment that explains null-containing fields vs
withDefault behavior to something like: "Fields that can contain null (i.e., no
withDefault) are required; others (with withDefault) are optional." Keep the
meaning intact and ensure the wording aligns with the file's existing English
documentation style.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/next-typed-href/src/nuqs.ts`:
- Line 16: Replace the lone Japanese inline comment in nuqs.ts with an English
equivalent to match the surrounding JSDoc; specifically update the comment that
explains null-containing fields vs withDefault behavior to something like:
"Fields that can contain null (i.e., no withDefault) are required; others (with
withDefault) are optional." Keep the meaning intact and ensure the wording
aligns with the file's existing English documentation style.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d55bd666-338d-49b7-9df5-b48aa459bddd

📥 Commits

Reviewing files that changed from the base of the PR and between 5ddeeee and fe58a8c.

📒 Files selected for processing (1)
  • packages/next-typed-href/src/nuqs.ts

Copy link
Copy Markdown

@akameco akameco left a comment

Choose a reason for hiding this comment

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

x

Copy link
Copy Markdown

@akameco akameco left a comment

Choose a reason for hiding this comment

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

LGTM!

3重のカリー化の部分がちょっと気になりますが、実装としては正しいと思います。
この辺の改良にちょっと案があるので、採用されるかは別にして後ほど提案PRします。

@amotarao amotarao merged commit 9532a6d into main Apr 30, 2026
2 checks passed
@amotarao amotarao deleted the feat/nuqs-require-search-params branch April 30, 2026 03:32
@github-actions github-actions Bot mentioned this pull request Apr 30, 2026
@amotarao
Copy link
Copy Markdown
Member Author

@akameco プロジェクトでも早めに入れたほうがいいと思うので、リリースします!
#61 は入れるならら入れたでまた調整すれば OK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants