Skip to content

fix(compiler-sfc): infer Vue ref wrapper types when source is unresolvable#14758

Open
ashishkr96 wants to merge 1 commit intovuejs:mainfrom
ashishkr96:fix/14729-defineprops-mayberef-union
Open

fix(compiler-sfc): infer Vue ref wrapper types when source is unresolvable#14758
ashishkr96 wants to merge 1 commit intovuejs:mainfrom
ashishkr96:fix/14729-defineprops-mayberef-union

Conversation

@ashishkr96
Copy link
Copy Markdown

@ashishkr96 ashishkr96 commented Apr 26, 2026

Close #14729

Summary

  • When MaybeRef<T[]> (or any other Vue ref-wrapper type) appears in a defineProps union and the vue import cannot be resolved by the SFC compiler — for example when the type lives in a separately-built package consumed by another app — resolveTypeReference throws inside inferRuntimeType. The throw is caught at the function's top-level try/catch and the entire branch collapses to UNKNOWN_TYPE. After the UNKNOWN_TYPE filtering in defineProps.ts, valid runtime types (e.g. Array) are silently dropped from the generated runtime props, producing Invalid prop: type check failed warnings at runtime even though the value is valid per the source TS type.
  • The fix has two parts:
    1. Catch the resolution failure locally inside the TSTypeReference case so the existing built-in name handling still gets a chance to run.
    2. Add fallbacks in that built-in switch for the well-known Vue wrapper types — Ref, ShallowRef, ComputedRef, WritableComputedRef (each → Object), MaybeRef<T> (→ Object | inferRuntimeType(T)) and MaybeRefOrGetter<T> (→ Object | Function | inferRuntimeType(T)). This mirrors the existing handling for Promise, Date, Map, etc.

Test plan

  • Added MaybeRef wrapped array type in interface inheritance chain mirroring the issue's exact code shape — confirms Array is now present for the options prop.
  • Added Vue ref wrapper types in union are inferred when source is unresolvable covering all six wrapper types.
  • Full packages/compiler-sfc test suite passes (455 tests).

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced type inference to gracefully handle unresolvable type references while maintaining support for Vue ref wrapper types.
  • Tests

    • Added comprehensive test cases for complex type reference and Vue ref wrapper type resolution scenarios.

…urce is unresolvable

When a `MaybeRef<T[]>` (or similar Vue ref wrapper) appears in a
`defineProps` union and the `vue` import cannot be resolved by the SFC
compiler (e.g. when the type lives in a separately-built package),
`resolveTypeReference` throws and the whole branch falls back to
`UNKNOWN_TYPE`. After UNKNOWN filtering, valid runtime types like
`Array` are silently dropped from the generated runtime props,
producing incorrect `Invalid prop` warnings at runtime.

Catch the resolution failure locally so the built-in name handling
still runs, and add fallbacks for the well-known Vue wrapper types
(`Ref`, `ShallowRef`, `ComputedRef`, `WritableComputedRef`,
`MaybeRef`, `MaybeRefOrGetter`).

close vuejs#14729
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

📝 Walkthrough

Walkthrough

The changes improve runtime props type inference in Vue's SFC compiler by adding error tolerance to type resolution and explicit type mappings for Vue ref wrapper types (MaybeRef, Ref, ShallowRef, ComputedRef, WritableComputedRef, MaybeRefOrGetter), enabling correct inference when these wrappers are unresolvable but used in defineProps. Two test cases validate the fixes.

Changes

Cohort / File(s) Summary
Test Coverage
packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
Added two test cases for #14729: one validating MaybeRef<...[]> inference through type alias chains includes Array, another testing multiple Vue ref-wrapper types from unresolvable packages with strict runtime type assertions per prop.
Type Inference Logic
packages/compiler-sfc/src/script/resolveType.ts
Enhanced inferRuntimeType to catch resolveTypeReference errors and fall back to identifier-based inference; added explicit runtime type mappings for Vue ref wrappers—Ref/ShallowRef/ComputedRef/WritableComputedRef map to Object, while MaybeRef/MaybeRefOrGetter infer recursively from their first type parameter with Function included for MaybeRefOrGetter.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ready to merge, scope: sfc, :hammer: p3-minor-bug

Suggested reviewers

  • LittleSound
  • edison1105

Poem

🐰 Whiskers twitch with glee,
Vue's refs now flow so free,
No lost Arrays today,
Our inference saves the way!
MaybeRef's mystery undone,
Runtime types have won!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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
Title check ✅ Passed The PR title accurately describes the main change: fixing Vue ref wrapper type inference when the source package is unresolvable, which directly addresses the core issue.
Linked Issues check ✅ Passed The PR implementation fully addresses issue #14729: it catches resolution failures in inferRuntimeType, adds built-in fallbacks for Vue wrapper types (including MaybeRef), and includes test cases validating the fix.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing #14729: modifications to resolveType.ts handle the unresolvable source issue, and test additions verify the fix without introducing unrelated functionality.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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

@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/compiler-sfc/__tests__/compileScript/resolveType.spec.ts (1)

806-860: Consider relocating these tests out of type alias declaration.

Both new cases primarily exercise ref-wrapper inference when the type source is unresolvable; the second one doesn’t involve a type alias at all, and the first is really about interface inheritance. They’d read more naturally under their own describe('ref wrapper inference', ...) (or in external type imports next to the unresolvable-extends test). Purely organizational — behavior and assertions look correct.

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

In `@packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts` around
lines 806 - 860, The two tests ("MaybeRef wrapped array type in interface
inheritance chain" and "Vue ref wrapper types in union are inferred when source
is unresolvable") are misplaced under "type alias declaration" and should be
moved to a more appropriate suite that focuses on ref-wrapper inference or
external type imports; relocate the tests (the blocks referencing MaybeRef, Ref,
ISelectable, XSelectProps, defineProps and resolve) into a new or existing
describe('ref wrapper inference', ...) (or next to the unresolvable-extends
test) so their intent is clearer, ensuring you keep the existing test bodies and
expectations unchanged while updating the test file structure only.
🤖 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/compiler-sfc/__tests__/compileScript/resolveType.spec.ts`:
- Around line 806-860: The two tests ("MaybeRef wrapped array type in interface
inheritance chain" and "Vue ref wrapper types in union are inferred when source
is unresolvable") are misplaced under "type alias declaration" and should be
moved to a more appropriate suite that focuses on ref-wrapper inference or
external type imports; relocate the tests (the blocks referencing MaybeRef, Ref,
ISelectable, XSelectProps, defineProps and resolve) into a new or existing
describe('ref wrapper inference', ...) (or next to the unresolvable-extends
test) so their intent is clearer, ensuring you keep the existing test bodies and
expectations unchanged while updating the test file structure only.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ac56e932-bff8-4c07-a4d3-f49e5e972792

📥 Commits

Reviewing files that changed from the base of the PR and between 3310eea and c134535.

📒 Files selected for processing (2)
  • packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
  • packages/compiler-sfc/src/script/resolveType.ts

@ashishkr96
Copy link
Copy Markdown
Author

@edison1105 Can you please review.

@edison1105 edison1105 added scope: sfc 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels May 6, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 6, 2026

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@14758
npm i https://pkg.pr.new/@vue/compiler-core@14758
yarn add https://pkg.pr.new/@vue/compiler-core@14758.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@14758
npm i https://pkg.pr.new/@vue/compiler-dom@14758
yarn add https://pkg.pr.new/@vue/compiler-dom@14758.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@14758
npm i https://pkg.pr.new/@vue/compiler-sfc@14758
yarn add https://pkg.pr.new/@vue/compiler-sfc@14758.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@14758
npm i https://pkg.pr.new/@vue/compiler-ssr@14758
yarn add https://pkg.pr.new/@vue/compiler-ssr@14758.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@14758
npm i https://pkg.pr.new/@vue/reactivity@14758
yarn add https://pkg.pr.new/@vue/reactivity@14758.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@14758
npm i https://pkg.pr.new/@vue/runtime-core@14758
yarn add https://pkg.pr.new/@vue/runtime-core@14758.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@14758
npm i https://pkg.pr.new/@vue/runtime-dom@14758
yarn add https://pkg.pr.new/@vue/runtime-dom@14758.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@14758
npm i https://pkg.pr.new/@vue/server-renderer@14758
yarn add https://pkg.pr.new/@vue/server-renderer@14758.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@14758
npm i https://pkg.pr.new/@vue/shared@14758
yarn add https://pkg.pr.new/@vue/shared@14758.tgz

vue

pnpm add https://pkg.pr.new/vue@14758
npm i https://pkg.pr.new/vue@14758
yarn add https://pkg.pr.new/vue@14758.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@14758
npm i https://pkg.pr.new/@vue/compat@14758
yarn add https://pkg.pr.new/@vue/compat@14758.tgz

commit: c134535

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 106 kB 40 kB 35.9 kB
vue.global.prod.js 164 kB 60 kB 53.3 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 48.6 kB 18.9 kB 17.3 kB
createApp 56.7 kB 21.9 kB 20.1 kB
createSSRApp 61 kB 23.7 kB 21.6 kB
defineCustomElement 62.9 kB 23.9 kB 21.8 kB
overall 71.5 kB 27.3 kB 24.9 kB

@edison1105
Copy link
Copy Markdown
Member

/ecosystem-ci run

@edison1105
Copy link
Copy Markdown
Member

Thanks, LGTM~

@vue-bot
Copy link
Copy Markdown
Contributor

vue-bot commented May 6, 2026

📝 Ran ecosystem CI: Open

suite result latest scheduled
quasar success success
primevue success success
language-tools success success
radix-vue success success
nuxt failure failure
pinia success success
test-utils success success
router success success
vant success success
vue-i18n success success
vitepress success success
vite-plugin-vue success success
vuetify success success
vueuse success success
vue-macros success success
vue-simple-compiler success success

@edison1105 edison1105 added the ready to merge The PR is ready to be merged. label May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready to merge The PR is ready to be merged. scope: sfc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

defineProps runtime props inference misses Array from MaybeRef<T[]> in union type after upgrading to Vue 3.5.31

3 participants