Source: monkey-patch.js

/**
 * Operators object that maps operator names to their corresponding symbols.
 * @type {Object}
 */
let Operators = {
  add: '+',
  mul: '*',
  div: '/',
  equals: '==',
  pow: '**',
  neg: '-',
  lessThan: '<',
  greaterThan: '>'
};

/**
 * Object that handles boolean operations.
 * @type {Object}
 */
let booleanHandler = Object.create(null);

/**
 * Handles boolean operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {*} - The result of the operation.
 */
booleanHandler.boolean = function (op, other) {
  if (op === 'equals') {
    return this == other;
  }
  let className = other?.constructor?.name || typeof other;
  throw new Error(`Boolean "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

/**
 * Handles object operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {*} - The result of the operation.
 */
booleanHandler.object = function (op, other) {
  if (op === 'add') {
    return other.add(Number(this));
  }
  throw new Error(`Boolean "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

/**
 * Object that handles function operations.
 * @type {Object}
 */
let functionHandler = Object.create(null);

/**
 * Handles boolean operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {Function} - A function that performs the operation.
 */
functionHandler.boolean = function (op, other) {
  return (...x) => this(...x)[op](Number(other));
};

/**
 * Handles function operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {Function} - A function that performs the operation.
 */
functionHandler.function = function (op, other) {
  return (...x) => {
    try {
      return this(...x)[op](other(...x));
    } catch (e) {
      throw new Error(`Unsupported ${op} for ${other}`);
    }
  };
};

/**
 * Handles object operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {Function} - A function that performs the operation.
 */
functionHandler.object = function (op, other) {
  return (...x) => {
    try {
      return this(...x)[op](other);
    } catch (e) {
      throw new Error(`Unsupported ${op} for ${other}`);
    }
  };
};

/**
 * Default handler for boolean and function operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @throws {Error} - Throws an error indicating the operation is not supported.
 */
booleanHandler.default = functionHandler.default = function (op, other) {
  throw new Error(`Boolean "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

/**
 * Object that handles string operations.
 * @type {Object}
 */
let stringHandler = Object.create(null);

/**
 * Default handler for string operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @throws {Error} - Throws an error indicating the operation is not supported.
 */
stringHandler.default = function (op, other) {
  if (op == 'equals') {
    return this == other;
  } else if (op == 'lessThan') {
    return this < other;
  } else if (op == 'greaterThan') {
    return this > other;
  }
  throw new Error(`String "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

/**
 * Handles function operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {string} - The result of the operation.
 */
stringHandler.function = function (op, other) {
  if (op == 'add') {
    return this + String(other);
  }
  throw new Error(`String "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

/**
 * Handles boolean operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {string} - The result of the operation.
 */
stringHandler.boolean = function (op, other) {
  if (op == 'add') {
    return this + String(other);
  } else if (op == 'equals') {
    return this == other;
  } else if (op == 'lessThan') {
    return this < other;
  } else if (op == 'greaterThan') {
    return this > other;
  }
  throw new Error(`String "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

/**
 * Handles object operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {string} - The result of the operation.
 */
stringHandler.object = function (op, other) {
  if (op == 'add') {
    return this + String(other);
  }
  throw new Error(`String "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

/**
 * Handles string operations.
 * @param {string} op - The operator.
 * @param {*} other - The other operand.
 * @returns {string} - The result of the operation.
 */
stringHandler.string = function (op, other) {
  if (op == 'add') {
    return this + other;
  } else if (op == 'equals') {
    return this == other;
  } else if (op == 'lessThan') {
    return this < other;
  } else if (op == 'greaterThan') {
    return this > other;
  }
  throw new Error(`String "${this}" does not support "${Operators[op] || op}" for "${other}"`);
};

// Monkey patching the prototype objects
for (let op in Operators) {
  Boolean.prototype[op] = function (other) {
    return booleanHandler[typeof other]?.call(this, op, other) || booleanHandler.default.call(this, op, other);
  };
  Function.prototype[op] = function (other) {
    return functionHandler[typeof other]?.call(this, op, other) || functionHandler.default.call(this, op, other);
  };
  String.prototype[op] = function (other) {
    return stringHandler[typeof other]?.call(this, op, other) || stringHandler.default.call(this, op, other);
  };
}