File tree Expand file tree Collapse file tree 2 files changed +58
-1
lines changed Expand file tree Collapse file tree 2 files changed +58
-1
lines changed Original file line number Diff line number Diff line change @@ -12,8 +12,15 @@ export function deepCopy(src: any, des: any): void {
1212 while ( stack . length ) {
1313 const { src, des } = stack . pop ( ) !
1414
15+ // using `Object.keys` which skips prototype properties
1516 Object . keys ( src ) . forEach ( key => {
16- if ( isNotObjectOrIsArray ( src [ key ] ) || isNotObjectOrIsArray ( des [ key ] ) ) {
17+ // if src[key] is an object/array, set des[key]
18+ // to empty object/array to prevent setting by reference
19+ if ( isObject ( src [ key ] ) && ! isObject ( des [ key ] ) ) {
20+ des [ key ] = Array . isArray ( src [ key ] ) ? [ ] : { }
21+ }
22+
23+ if ( isNotObjectOrIsArray ( des [ key ] ) || isNotObjectOrIsArray ( src [ key ] ) ) {
1724 // replace with src[key] when:
1825 // src[key] or des[key] is not an object, or
1926 // src[key] or des[key] is an array
Original file line number Diff line number Diff line change 1+ import { deepCopy } from '../src/index'
2+
3+ test ( 'deepCopy merges without mutating src argument' , ( ) => {
4+ const msg1 = {
5+ hello : 'Greetings' ,
6+ about : {
7+ title : 'About us'
8+ } ,
9+ overwritten : 'Original text' ,
10+ fruit : [ { name : 'Apple' } ]
11+ }
12+ const copy1 = structuredClone ( msg1 )
13+
14+ const msg2 = {
15+ bye : 'Goodbye' ,
16+ about : {
17+ content : 'Some text'
18+ } ,
19+ overwritten : 'New text' ,
20+ fruit : [ { name : 'Strawberry' } ] ,
21+ // @ts -ignore
22+ car : ( { plural } ) => plural ( [ 'car' , 'cars' ] )
23+ }
24+
25+ const merged = { }
26+
27+ deepCopy ( msg1 , merged )
28+ deepCopy ( msg2 , merged )
29+
30+ expect ( merged ) . toMatchInlineSnapshot ( `
31+ {
32+ "about": {
33+ "content": "Some text",
34+ "title": "About us",
35+ },
36+ "bye": "Goodbye",
37+ "car": [Function],
38+ "fruit": [
39+ {
40+ "name": "Strawberry",
41+ },
42+ ],
43+ "hello": "Greetings",
44+ "overwritten": "New text",
45+ }
46+ ` )
47+
48+ // should not mutate source object
49+ expect ( msg1 ) . toStrictEqual ( copy1 )
50+ } )
You can’t perform that action at this time.
0 commit comments