// type Diff = T; // 比较两个数组是否相等 function arraysEqual(a: T[], b: T[]): boolean { if (a.length !== b.length) return false; const counter = new Map(); for (const value of a) { counter.set(value, (counter.get(value) || 0) + 1); } for (const value of b) { const count = counter.get(value); if (count === undefined || count === 0) { return false; } counter.set(value, count - 1); } return true; } // 深度对比两个值 // function deepEqual(oldVal: T, newVal: T): boolean { // if ( // typeof oldVal === 'object' && // oldVal !== null && // typeof newVal === 'object' && // newVal !== null // ) { // return Array.isArray(oldVal) && Array.isArray(newVal) // ? arraysEqual(oldVal, newVal) // : diff(oldVal as any, newVal as any) === null; // } else { // return oldVal === newVal; // } // } // // diff 函数 // function diff( // oldObj: T, // newObj: T, // ignoreFields: (keyof T)[] = [], // ): { [K in keyof T]?: Diff } | null { // const difference: { [K in keyof T]?: Diff } = {}; // for (const key in oldObj) { // if (ignoreFields.includes(key)) continue; // const oldValue = oldObj[key]; // const newValue = newObj[key]; // if (!deepEqual(oldValue, newValue)) { // difference[key] = newValue; // } // } // return Object.keys(difference).length === 0 ? null : difference; // } type DiffResult = Partial<{ [K in keyof T]: T[K] extends object ? DiffResult : T[K]; }>; function diff>(obj1: T, obj2: T): DiffResult { function findDifferences(o1: any, o2: any): any { if (Array.isArray(o1) && Array.isArray(o2)) { if (!arraysEqual(o1, o2)) { return o2; } return undefined; } if ( typeof o1 === 'object' && typeof o2 === 'object' && o1 !== null && o2 !== null ) { const diffResult: any = {}; const keys = new Set([...Object.keys(o1), ...Object.keys(o2)]); keys.forEach((key) => { const valueDiff = findDifferences(o1[key], o2[key]); if (valueDiff !== undefined) { diffResult[key] = valueDiff; } }); return Object.keys(diffResult).length > 0 ? diffResult : undefined; } return o1 === o2 ? undefined : o2; } return findDifferences(obj1, obj2); } export { arraysEqual, diff };