fix(reactivity): correctly handle method calls on user-extended arrays (#11760)

close #11759
This commit is contained in:
Tycho 2024-09-03 17:32:13 +08:00 committed by GitHub
parent 52cdb0f991
commit 9817c80187
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 3 deletions

View File

@ -724,6 +724,27 @@ describe('reactivity/reactive/Array', () => {
expect(state.things.forEach('foo', 'bar', 'baz')).toBeUndefined()
expect(state.things.map('foo', 'bar', 'baz')).toEqual(['1', '2', '3'])
expect(state.things.some('foo', 'bar', 'baz')).toBe(true)
{
class Collection extends Array {
find(matcher: any) {
return super.find(matcher)
}
}
const state = reactive({
// @ts-expect-error
things: new Collection({ foo: '' }),
})
const bar = computed(() => {
return state.things.find((obj: any) => obj.foo === 'bar')
})
bar.value
state.things[0].foo = 'bar'
expect(bar.value).toEqual({ foo: 'bar' })
}
})
})
})

View File

@ -242,9 +242,13 @@ function apply(
const needsWrap = arr !== self && !isShallow(self)
// @ts-expect-error our code is limited to es2016 but user code is not
const methodFn = arr[method]
// @ts-expect-error
if (methodFn !== arrayProto[method]) {
const result = methodFn.apply(arr, args)
// #11759
// If the method being called is from a user-extended Array, the arguments will be unknown
// (unknown order and unknown parameter types). In this case, we skip the shallowReadArray
// handling and directly call apply with self.
if (methodFn !== arrayProto[method as any]) {
const result = methodFn.apply(self, args)
return needsWrap ? toReactive(result) : result
}