diff --git a/packages/reactivity/__tests__/reactiveArray.spec.ts b/packages/reactivity/__tests__/reactiveArray.spec.ts index 897a3b1ed9c..960c16e0b3b 100644 --- a/packages/reactivity/__tests__/reactiveArray.spec.ts +++ b/packages/reactivity/__tests__/reactiveArray.spec.ts @@ -625,8 +625,74 @@ describe('reactivity/reactive/Array', () => { test('extend methods', () => { class Collection extends Array { - find(id: any) { - return super.find(obj => obj.id === id) + // @ts-expect-error + every(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + return super.every(obj => obj.id === foo) + } + + // @ts-expect-error + filter(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + return super.filter(obj => obj.id === foo) + } + + // @ts-expect-error + find(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + return super.find(obj => obj.id === foo) + } + + // @ts-expect-error + findIndex(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + return super.findIndex(obj => obj.id === bar) + } + + findLast(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + // @ts-expect-error our code is limited to es2016 but user code is not + return super.findLast(obj => obj.id === bar) + } + + findLastIndex(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + return super.findIndex(obj => obj.id === bar) + } + + // @ts-expect-error + forEach(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + } + + // @ts-expect-error + map(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + return super.map(obj => obj.value) + } + + // @ts-expect-error + some(foo: any, bar: any, baz: any) { + expect(foo).toBe('foo') + expect(bar).toBe('bar') + expect(baz).toBe('baz') + return super.some(obj => obj.id === baz) } } @@ -634,10 +700,22 @@ describe('reactivity/reactive/Array', () => { things: new Collection(), }) - const val = { id: 'foo', value: 'bar' } - state.things.push(val) - - expect(state.things.find('foo')).toBe(val) + const foo = { id: 'foo', value: '1' } + const bar = { id: 'bar', value: '2' } + const baz = { id: 'baz', value: '3' } + state.things.push(foo) + state.things.push(bar) + state.things.push(baz) + + expect(state.things.every('foo', 'bar', 'baz')).toBe(false) + expect(state.things.filter('foo', 'bar', 'baz')).toEqual([foo]) + expect(state.things.find('foo', 'bar', 'baz')).toBe(foo) + expect(state.things.findIndex('foo', 'bar', 'baz')).toBe(1) + expect(state.things.findLast('foo', 'bar', 'baz')).toBe(bar) + expect(state.things.findLastIndex('foo', 'bar', 'baz')).toBe(1) + 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) }) }) }) diff --git a/packages/reactivity/src/arrayInstrumentations.ts b/packages/reactivity/src/arrayInstrumentations.ts index 51955a1bf81..58c31835dfd 100644 --- a/packages/reactivity/src/arrayInstrumentations.ts +++ b/packages/reactivity/src/arrayInstrumentations.ts @@ -47,42 +47,42 @@ export const arrayInstrumentations: Record = { fn: (item: unknown, index: number, array: unknown[]) => unknown, thisArg?: unknown, ) { - return apply(this, 'every', fn, thisArg) + return apply(this, 'every', fn, thisArg, undefined, arguments) }, filter( fn: (item: unknown, index: number, array: unknown[]) => unknown, thisArg?: unknown, ) { - return apply(this, 'filter', fn, thisArg, v => v.map(toReactive)) + return apply(this, 'filter', fn, thisArg, v => v.map(toReactive), arguments) }, find( fn: (item: unknown, index: number, array: unknown[]) => boolean, thisArg?: unknown, ) { - return apply(this, 'find', fn, thisArg, toReactive) + return apply(this, 'find', fn, thisArg, toReactive, arguments) }, findIndex( fn: (item: unknown, index: number, array: unknown[]) => boolean, thisArg?: unknown, ) { - return apply(this, 'findIndex', fn, thisArg) + return apply(this, 'findIndex', fn, thisArg, undefined, arguments) }, findLast( fn: (item: unknown, index: number, array: unknown[]) => boolean, thisArg?: unknown, ) { - return apply(this, 'findLast', fn, thisArg, toReactive) + return apply(this, 'findLast', fn, thisArg, toReactive, arguments) }, findLastIndex( fn: (item: unknown, index: number, array: unknown[]) => boolean, thisArg?: unknown, ) { - return apply(this, 'findLastIndex', fn, thisArg) + return apply(this, 'findLastIndex', fn, thisArg, undefined, arguments) }, // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement @@ -91,7 +91,7 @@ export const arrayInstrumentations: Record = { fn: (item: unknown, index: number, array: unknown[]) => unknown, thisArg?: unknown, ) { - return apply(this, 'forEach', fn, thisArg) + return apply(this, 'forEach', fn, thisArg, undefined, arguments) }, includes(...args: unknown[]) { @@ -116,7 +116,7 @@ export const arrayInstrumentations: Record = { fn: (item: unknown, index: number, array: unknown[]) => unknown, thisArg?: unknown, ) { - return apply(this, 'map', fn, thisArg) + return apply(this, 'map', fn, thisArg, undefined, arguments) }, pop() { @@ -161,7 +161,7 @@ export const arrayInstrumentations: Record = { fn: (item: unknown, index: number, array: unknown[]) => unknown, thisArg?: unknown, ) { - return apply(this, 'some', fn, thisArg) + return apply(this, 'some', fn, thisArg, undefined, arguments) }, splice(...args: unknown[]) { @@ -236,12 +236,13 @@ function apply( fn: (item: unknown, index: number, array: unknown[]) => unknown, thisArg?: unknown, wrappedRetFn?: (result: any) => unknown, + args?: IArguments, ) { const arr = shallowReadArray(self) let methodFn // @ts-expect-error our code is limited to es2016 but user code is not if ((methodFn = arr[method]) !== arrayProto[method]) { - return methodFn.apply(arr, arrayProto.slice.call(arguments, 2)) + return methodFn.apply(arr, args) } let needsWrap = false