Untitled
type ChangeDetail<T> = { originalVal: T, currentVal: T } type Changes<T> = { [Key in keyof T]?: T[Key] extends object ? Changes<T[Key]> : ChangeDetail<T[Key]> } function compare<T extends object>(oldObj: T, newObj: T): Changes<T>{ const result: Changes<T> = {}; for(const key in {...oldObj, ...newObj}){ const oldObjHasKey = oldObj.hasOwnProperty(key) const newObjHasKey = newObj.hasOwnProperty(key) const keyOfT = key as keyof T; // type specification if(oldObjHasKey && newObjHasKey){ // old and new object has the same key const oldVal = oldObj[keyOfT] const newVal = newObj[keyOfT] if (oldVal !== newVal) { // Only show the difference fields if(oldVal !== null && newVal !== null && typeof oldVal === 'object' && typeof newVal === 'object'){ // recursive call const nestedChanges = compare(oldVal, newVal); if(Object.keys(nestedChanges).length > 0){ result[key as keyof T] = nestedChanges as Changes<T>[keyof T]; } } else{ result[keyOfT] = { originalVal: oldObj[keyOfT], currentVal: newObj[keyOfT] } as Changes<T>[keyof T] } } }else if(oldObjHasKey){ // oldObject has the key that newObject doesn't result[keyOfT] = { originalVal: oldObj[keyOfT], currentVal: undefined } as Changes<T>[keyof T] }else if(newObjHasKey){ // newObject has the key that oldObject doesn't result[keyOfT] = { originalVal: undefined, currentVal: newObj[keyOfT] } as Changes<T>[keyof T] } } return result } interface MyObject { name?: string; age?: number; email? :string; address?: { street?: string; city?: string; zipcode?: number, moreInfo?: { ward?: string, district?: string }, description: { text: string, no: number } }; } const oldData: MyObject = { name: "Long", email: "longnb6@haha.com", address: { street: "123 batrieu", city: "hanoi", zipcode: 10000, moreInfo: { ward: 'hangbo', district: 'hoankiem' }, description: { text: '1', no: 2 } } }; const newData: MyObject = { age: 28, email: "dungnh6@haha.com", address: { street: "tran khanh tong", city: "hanoi", moreInfo: { ward: 'daimo', district: 'nam tu liem' }, description: { text: '1', no: 2 } } }; const result = compare(oldData, newData); console.log(result);
Leave a Comment