Untitled
unknown
typescript
a year ago
2.6 kB
10
Indexable
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);Editor is loading...
Leave a Comment