Skip to content

fix(types): prevent string widening in SpeculationRules nested types#737

Merged
harlan-zw merged 1 commit intomainfrom
fix/speculation-rules-type-widening
Apr 10, 2026
Merged

fix(types): prevent string widening in SpeculationRules nested types#737
harlan-zw merged 1 commit intomainfrom
fix/speculation-rules-type-widening

Conversation

@harlan-zw
Copy link
Copy Markdown
Collaborator

@harlan-zw harlan-zw commented Apr 10, 2026

🔗 Linked issue

N/A

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking change

📚 Description

When using useHead with speculation rules, TypeScript widens nested literal values like source: 'list' and requires: ['anonymous-client-ip-when-cross-origin'] to string, which fails to match the discriminated union of SpeculationRuleList | SpeculationRuleDocument. This causes a type error that falls through to ApplicationJsonScript.

Merges SpeculationRuleBase, SpeculationRuleList, and SpeculationRuleDocument into a single SpeculationRule interface. Discrimination is now structural (urls vs where presence) rather than relying on literal source values. Fields that previously required exact literals (source, requires, relative_to, target_hint) now use the (string & Record<never, never>) pattern already established throughout the codebase for autocomplete with flexible matching.

Summary by CodeRabbit

  • Breaking Changes
    • Updated the structure of prefetch and prerender configuration in speculation rules to use a unified interface supporting both list and document-based rules.
    • Expanded field value options to support custom values in addition to predefined options for speculative loading rules.

Merges SpeculationRuleBase, SpeculationRuleList, and SpeculationRuleDocument
into a single SpeculationRule interface. Discrimination is now structural
(urls vs where) rather than relying on literal source values that TypeScript
widens to string inside useHead, breaking the discriminated union.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d551407b-5dcc-41d3-b6c8-faf69fa60efd

📥 Commits

Reviewing files that changed from the base of the PR and between b147fba and 2224c9a.

📒 Files selected for processing (1)
  • packages/unhead/src/types/schema/struct/speculationRules.ts

📝 Walkthrough

Walkthrough

The SpeculationRules schema consolidates three separate interfaces (SpeculationRuleBase, SpeculationRuleList, SpeculationRuleDocument) into a single unified SpeculationRule interface with optional fields. Discriminated union fields are widened to accept custom string values alongside existing literal options.

Changes

Cohort / File(s) Summary
SpeculationRules Type Consolidation
packages/unhead/src/types/schema/struct/speculationRules.ts
Merged three separate rule interfaces into one SpeculationRule with optional source, urls, and where fields. Widened string-literal fields (source, relative_to, requires element, target_hint) to permit custom string values via (string & Record<never, never>) union extension. Updated field documentation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Three interfaces once stood apart with pride,
Now bundled into one with options wide!
Custom strings flow through, rules consolidated bright,
Schema's dressed anew in flexibility's light! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: preventing string widening in SpeculationRules types through a refactoring approach.
Description check ✅ Passed The description follows the template structure with linked issue, type of change checkbox (bug fix selected), and detailed explanation of the problem and solution.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/speculation-rules-type-widening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Bundle Size Gzipped
Client (Minimal) 10.7 kB 4.4 kB
Server (Minimal) 10.6 kB 4.3 kB
Vue Client (Minimal) 11.8 kB 4.8 kB
Vue Server (Minimal) 11.6 kB 4.7 kB

@harlan-zw harlan-zw merged commit 2d097ca into main Apr 10, 2026
8 checks passed
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.

1 participant