diff.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. type Diff<T = any> = T;
  2. // 比较两个数组是否相等
  3. function arraysEqual<T>(a: T[], b: T[]): boolean {
  4. if (a.length !== b.length) return false;
  5. const counter = new Map<T, number>();
  6. for (const value of a) {
  7. counter.set(value, (counter.get(value) || 0) + 1);
  8. }
  9. for (const value of b) {
  10. const count = counter.get(value);
  11. if (count === undefined || count === 0) {
  12. return false;
  13. }
  14. counter.set(value, count - 1);
  15. }
  16. return true;
  17. }
  18. // 深度对比两个值
  19. function deepEqual<T>(oldVal: T, newVal: T): boolean {
  20. if (
  21. typeof oldVal === 'object' &&
  22. oldVal !== null &&
  23. typeof newVal === 'object' &&
  24. newVal !== null
  25. ) {
  26. return Array.isArray(oldVal) && Array.isArray(newVal)
  27. ? arraysEqual(oldVal, newVal)
  28. : diff(oldVal as any, newVal as any) === null;
  29. } else {
  30. return oldVal === newVal;
  31. }
  32. }
  33. // 主要的 diff 函数
  34. function diff<T extends object>(
  35. oldObj: T,
  36. newObj: T,
  37. ignoreFields: (keyof T)[] = [],
  38. ): { [K in keyof T]?: Diff<T[K]> } | null {
  39. const difference: { [K in keyof T]?: Diff<T[K]> } = {};
  40. for (const key in oldObj) {
  41. if (ignoreFields.includes(key)) continue;
  42. const oldValue = oldObj[key];
  43. const newValue = newObj[key];
  44. if (!deepEqual(oldValue, newValue)) {
  45. difference[key] = newValue;
  46. }
  47. }
  48. return Object.keys(difference).length === 0 ? null : difference;
  49. }
  50. export { arraysEqual, diff };