Skip to content

fix(types): widen ClassValue to accept fallthrough attrs values#14492

Open
edison1105 wants to merge 1 commit intomainfrom
edison/fix/14489
Open

fix(types): widen ClassValue to accept fallthrough attrs values#14492
edison1105 wants to merge 1 commit intomainfrom
edison/fix/14489

Conversation

@edison1105
Copy link
Member

@edison1105 edison1105 commented Feb 28, 2026

close #14489

Summary by CodeRabbit

  • Tests

    • Enhanced test coverage for component attribute handling.
  • Refactor

    • Improved type system flexibility for class attribute computation.

@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

📝 Walkthrough

Walkthrough

Fixes a regression where assigning $attrs.class to a JSX class binding caused type errors. The fix extends the ClassValue type to include unknown and adds test coverage for the useAttrs hook with class bindings.

Changes

Cohort / File(s) Summary
Type definition update
packages/runtime-dom/src/jsx.ts
Extended ClassValue type union to include unknown, enabling compatibility with Record<string, unknown> when assigning $attrs.class.
Test coverage
packages-private/dts-test/tsx.test-d.tsx
Added test case demonstrating useAttrs() hook usage with class binding in JSX, validating the fix for the regression.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • #14441: Introduced the regression by changing HTMLAttributes.class from any to ClassValue | undefined, which this PR addresses by expanding the ClassValue type definition.

Suggested labels

scope: types, :exclamation: p4-important

Poem

🐰 A type was too strict, leaving class in a bind,
So we asked the union: could unknown be kind?
With attrs now flowing through JSX with grace,
The regression retreats—hop! peace in its place.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: widening ClassValue type to accept fallthrough attrs values, which directly addresses the linked issue.
Linked Issues check ✅ Passed The PR successfully implements the solution by adding unknown to ClassValue union, allowing $attrs.class (typed as unknown) to be accepted in :class assignments, resolving the reported regression.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the regression: ClassValue type widening and test additions to verify the fix work as intended.
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 (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch edison/fix/14489

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

@github-actions
Copy link

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 104 kB 39.3 kB 35.4 kB
vue.global.prod.js 162 kB 59.3 kB 52.8 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 47.8 kB 18.6 kB 17.1 kB
createApp 56 kB 21.7 kB 19.8 kB
createSSRApp 60.2 kB 23.4 kB 21.4 kB
defineCustomElement 61.6 kB 23.4 kB 21.4 kB
overall 70.4 kB 27 kB 24.6 kB

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 28, 2026

Open in StackBlitz

@vue/compiler-core

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

@vue/compiler-dom

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

@vue/compiler-sfc

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

@vue/compiler-ssr

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

@vue/reactivity

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

@vue/runtime-core

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

@vue/runtime-dom

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

@vue/server-renderer

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

@vue/shared

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

vue

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

@vue/compat

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

commit: b7f941c

@edison1105
Copy link
Member Author

/ecosystem-ci run

Copy link

@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-private/dts-test/tsx.test-d.tsx (1)

64-67: Add a negative assertion to prevent over-widening class typing.

Please pair this with a // @ts-expect-error`` case (e.g. class={123}) so the suite also enforces that invalid class values remain rejected.

Suggested dts-test addition
 // allow class passthrough from attrs
 const attrs = useAttrs()
 expectType<JSX.Element>(<div class={attrs.class} />)
+
+// `@ts-expect-error` invalid class value should still be rejected
+;<div class={123} />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages-private/dts-test/tsx.test-d.tsx` around lines 64 - 67, Add a
negative type assertion to the existing test that verifies class passthrough
from useAttrs does not over-widen the type: after the positive
expectType<JSX.Element>(<div class={attrs.class} />) add a failing case
annotated with // `@ts-expect-error` that tries an invalid class value (for
example class={123}) to ensure the compiler still rejects
non-string/non-string[] class values; update the tsx.test-d.tsx around the
useAttrs/attrs assertions so both the valid passthrough and the explicit
invalid-case are present.
🤖 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-private/dts-test/tsx.test-d.tsx`:
- Around line 64-67: Add a negative type assertion to the existing test that
verifies class passthrough from useAttrs does not over-widen the type: after the
positive expectType<JSX.Element>(<div class={attrs.class} />) add a failing case
annotated with // `@ts-expect-error` that tries an invalid class value (for
example class={123}) to ensure the compiler still rejects
non-string/non-string[] class values; update the tsx.test-d.tsx around the
useAttrs/attrs assertions so both the valid passthrough and the explicit
invalid-case are present.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea24576 and b1b1925.

📒 Files selected for processing (2)
  • packages-private/dts-test/tsx.test-d.tsx
  • packages/runtime-dom/src/jsx.ts

@vue-bot
Copy link
Contributor

vue-bot commented Feb 28, 2026

📝 Ran ecosystem CI: Open

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

@edison1105 edison1105 added ready to merge The PR is ready to be merged. scope: types 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Feb 28, 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: types

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3.5.29 regression: type error when assigning $attrs.class to :class

2 participants