option-utils.js 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /**
  2. * @fileoverview Utilities to operate on option objects.
  3. * @author Josh Goldberg
  4. */
  5. "use strict";
  6. /**
  7. * Determines whether any of input's properties are different
  8. * from values that already exist in original.
  9. * @template T
  10. * @param {Partial<T>} input New value.
  11. * @param {T} original Original value.
  12. * @returns {boolean} Whether input includes an explicit difference.
  13. */
  14. function containsDifferentProperty(input, original) {
  15. if (input === original) {
  16. return false;
  17. }
  18. if (
  19. typeof input !== typeof original ||
  20. Array.isArray(input) !== Array.isArray(original)
  21. ) {
  22. return true;
  23. }
  24. if (Array.isArray(input)) {
  25. return (
  26. input.length !== original.length ||
  27. input.some((value, i) =>
  28. containsDifferentProperty(value, original[i]),
  29. )
  30. );
  31. }
  32. if (typeof input === "object") {
  33. if (input === null || original === null) {
  34. return true;
  35. }
  36. const inputKeys = Object.keys(input);
  37. const originalKeys = Object.keys(original);
  38. return (
  39. inputKeys.length !== originalKeys.length ||
  40. inputKeys.some(
  41. inputKey =>
  42. !Object.hasOwn(original, inputKey) ||
  43. containsDifferentProperty(
  44. input[inputKey],
  45. original[inputKey],
  46. ),
  47. )
  48. );
  49. }
  50. return true;
  51. }
  52. module.exports = {
  53. containsDifferentProperty,
  54. };