Skip to content

fix(runtime-core): relax function ref callback variance#14658

Closed
Misrilal-Sah wants to merge 1 commit intovuejs:mainfrom
Misrilal-Sah:fix-13969-function-ref-variance
Closed

fix(runtime-core): relax function ref callback variance#14658
Misrilal-Sah wants to merge 1 commit intovuejs:mainfrom
Misrilal-Sah:fix-13969-function-ref-variance

Conversation

@Misrilal-Sah
Copy link
Copy Markdown

@Misrilal-Sah Misrilal-Sah commented Mar 31, 2026

Issue link
#13969

Description
This PR adjusts function-ref typing so callbacks with narrower HTMLElement parameter types are accepted (for example HTMLFormElement on form refs).

Why
Template/function refs should allow element-specific callback parameter typing, but current type variance rejected valid narrower element types.

Changes
Updated VNode function ref callback typing to be bivariant.
Added dts regression cases for HTMLFormElement/HTMLDivElement function refs.

Summary by CodeRabbit

  • Tests
    • Extended TypeScript test coverage for element reference callback type validation, improving type inference accuracy and IDE support for developers using element refs.

Copilot AI review requested due to automatic review settings March 31, 2026 05:53
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 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: b051055b-bca4-43ce-9b59-262714795f79

📥 Commits

Reviewing files that changed from the base of the PR and between fa23116 and 48957e9.

📒 Files selected for processing (2)
  • packages-private/dts-test/h.test-d.ts
  • packages/runtime-core/src/vnode.ts

📝 Walkthrough

Walkthrough

The changes update Vue's ref callback typing system by refactoring VNodeRef to use bivariant encoding instead of direct function signatures, and add test cases validating ref inference for specific element types like HTMLFormElement and HTMLDivElement.

Changes

Cohort / File(s) Summary
Test Coverage Expansion
packages-private/dts-test/h.test-d.ts
Added two new valid test cases for h element ref inference, validating callback refs with specific element types (HTMLFormElement and HTMLDivElement).
Type System Enhancement
packages/runtime-core/src/vnode.ts
Refactored VNodeRef type to use bivariant-callback encoding via object with bivarianceHack method instead of direct callable signature, enabling more flexible assignment of specific element/ref callback types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 With bivariant tricks we hop and bound,
Refs now dance on safer ground,
Types align both far and near,
Element callbacks crystal clear!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: updating VNodeRef typing to use bivariant encoding for function ref callbacks, which directly addresses the core issue of relaxing variance constraints.
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 unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Vue’s runtime-core TypeScript typings for function refs so ref callbacks can use narrower DOM element parameter types (e.g. HTMLFormElement for <form> refs), addressing #13969.

Changes:

  • Made VNodeRef function-ref callbacks bivariant to relax parameter variance for element-specific callback typing.
  • Added DTS regression coverage ensuring h('form' | 'div', { ref: (el: HTMLFormElement/HTMLDivElement | null) => {} }) type-checks.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/runtime-core/src/vnode.ts Updates VNodeRef callback typing to be bivariant so narrower element parameter types are accepted.
packages-private/dts-test/h.test-d.ts Adds DTS regression cases for HTMLFormElement / HTMLDivElement function refs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

) => void)
| {
// Bivariant callback param allows assigning more specific element types,
// e.g. (el: HTMLFormElement | null) => void for <form ref="...">.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The example in the new comment is slightly misleading for function refs: <form ref="..."> reads like a string ref. Consider changing it to something like <form :ref="(el: HTMLFormElement | null) => {}"> (or otherwise clarify it’s a function ref) so the comment matches the feature being typed here.

Suggested change
// e.g. (el: HTMLFormElement | null) => void for <form ref="...">.
// e.g. (el: HTMLFormElement | null) => void for
// <form :ref="(el: HTMLFormElement | null) => {}">.

Copilot uses AI. Check for mistakes.
@edison1105
Copy link
Copy Markdown
Member

duplicate of #14529

@edison1105 edison1105 closed this Mar 31, 2026
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.

3 participants