Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { default as set, merge, mergeWith } from './utils/set';
export { default as warning, noteOnce } from './warning';
export { default as omit } from './omit';
export { default as toArray } from './Children/toArray';
export { default as mergeProps } from './mergeProps';
18 changes: 18 additions & 0 deletions src/mergeProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function mergeProps<A, B>(a: A, b: B): B & A;
function mergeProps<A, B, C>(a: A, b: B, c: C): C & B & A;
function mergeProps<A, B, C, D>(a: A, b: B, c: C, d: D): D & C & B & A;
function mergeProps(...items: any[]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

多个 useMergeProps?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前感觉不是很必要,因为每次 render 的 props 实例总是变化的,memo 不住呢

const ret: any = {};
for (const item of items) {
if (item) {
for (const key of Object.keys(item)) {
if (item[key] !== undefined) {
ret[key] = item[key];
}
}
}
}
return ret;
}

export default mergeProps;
52 changes: 52 additions & 0 deletions tests/mergeProps.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import mergeProps from '../src/mergeProps';

describe('mergeProps', () => {
it('merges two objects with later overriding earlier', () => {
const a = { foo: 1, bar: 2 };
const b = { bar: 3, baz: 4 };
expect(mergeProps(a, b)).toEqual({ foo: 1, bar: 3, baz: 4 });
});

it('excludes keys with undefined values', () => {
const a = { foo: 1, bar: undefined };
const b = { bar: 2 };
expect(mergeProps(a, b)).toEqual({ foo: 1, bar: 2 });
});

it('does not include key if value is undefined in last object', () => {
const a = { foo: 1 };
const b = { bar: undefined };
expect(mergeProps(a, b)).toEqual({ foo: 1 });
});

it('skips null and undefined items', () => {
const a = { foo: 1 };
expect(mergeProps(a, null as any)).toEqual({ foo: 1 });
expect(mergeProps(a, undefined as any)).toEqual({ foo: 1 });
expect(mergeProps(null as any, a)).toEqual({ foo: 1 });
expect(mergeProps(undefined as any, a)).toEqual({ foo: 1 });
});

it('merges three or more objects with rightmost winning', () => {
const a = { a: 1 };
const b = { a: 2, b: 2 };
const c = { a: 3, b: 3, c: 3 };
expect(mergeProps(a, b, c)).toEqual({ a: 3, b: 3, c: 3 });
});

it('returns empty object for no args', () => {
expect((mergeProps as (...items: any[]) => any)()).toEqual({});
});

it('returns copy of single object', () => {
const a = { foo: 1, bar: 2 };
expect((mergeProps as (...items: any[]) => any)(a)).toEqual({
foo: 1,
bar: 2,
});
});

it('handles empty objects', () => {
expect(mergeProps({}, { a: 1 }, {})).toEqual({ a: 1 });
});
});
Loading