fix(reactivity): handle objects with custom Symbol.toStringTag (fix #10483)#14874
fix(reactivity): handle objects with custom Symbol.toStringTag (fix #10483)#14874ATOM00blue wants to merge 1 commit into
Conversation
A custom `Symbol.toStringTag` changes the value returned by `toRawType`, which previously caused `getTargetType` to treat such objects (and subclasses of built-in collections that define a tag) as INVALID, so they were never wrapped in a reactive proxy. Fall back to prototype checks for these cases so they are correctly detected as a common object or collection. close vuejs#10483
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughFixed type detection in ChangesSymbol.toStringTag Detection Fix
🎯 2 (Simple) | ⏱️ ~12 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR fixes a reactivity edge case where reactive() / ref() fail to proxy values that define a custom Symbol.toStringTag, causing toRawType()-based target classification to mis-detect the value as INVALID.
Changes:
- Update target-type detection to fall back to prototype/
instanceofchecks whentoRawType()returns an unknown type (customSymbol.toStringTag). - Add tests covering a plain object with a custom
Symbol.toStringTag, plusMap/Arraysubclasses with custom tags.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/reactivity/src/reactive.ts | Adds fallback target-type detection when toRawType() is affected by custom Symbol.toStringTag. |
| packages/reactivity/tests/reactive.spec.ts | Adds regression tests for custom Symbol.toStringTag on objects and collection/array subtypes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (value instanceof Array || isPlainObject(value)) { | ||
| return TargetType.COMMON | ||
| } |
@vue/compiler-core
@vue/compiler-dom
@vue/compiler-sfc
@vue/compiler-ssr
@vue/reactivity
@vue/runtime-core
@vue/runtime-dom
@vue/server-renderer
@vue/shared
vue
@vue/compat
commit: |
| ) { | ||
| return TargetType.COLLECTION | ||
| } | ||
| if (value instanceof Array || isPlainObject(value)) { |
Fixes #10483
Problem
reactive()/ref()silently fail to make an object reactive when that object (or a subclass of a built-in collection) defines a customSymbol.toStringTag.getTargetTypedecides whether a value should be wrapped in a proxy based ontoRawType(value), which derives the type fromObject.prototype.toString.call(value). When a customSymbol.toStringTagis present, that call returns e.g."[object Goat]"instead of"[object Object]", sotoRawTypereturns"Goat",targetTypeMapfalls through toINVALID, and the value is returned untouched (not reactive).This is a real-world issue because such tags can come from third-party libraries, where the consumer cannot remove them. The object is mutated correctly but the UI never updates.
The same applies to subclasses of
Map/Setthat expose a custom tag, which are detected asINVALIDrather thanCOLLECTION.Fix
When
toRawTypedoes not match one of the known built-in types, fall back to prototype-based checks (instanceoffor collections/arrays, prototype comparison for plain objects) to determine the correctTargetType. The fast path for normal objects/arrays/collections is unchanged, so there is no overhead for the common case.Tests
Added cases in
reactive.spec.tscovering a plain object with a customSymbol.toStringTag, andMap/Arraysubclasses that define a tag. They fail onmainand pass with this change.Summary by CodeRabbit