removeOperations = (obj, keysToKeepOriginalValue = []) => {
	const newObj = /** @type {T} */ ({});
	for (const _key of Object.keys(obj)) {
		const key = /** @type {keyof T} */ (_key);
		const value = obj[key];
		const type = getValueType(value);
		if (type === VALUE_TYPE_OBJECT && keysToKeepOriginalValue.includes(key)) {
			newObj[key] = value;
			continue;
		}
		switch (type) {
			case VALUE_TYPE_UNDEFINED:
			case VALUE_TYPE_DELETE:
				break;
			case VALUE_TYPE_OBJECT:
				newObj[key] =
					/** @type {T[keyof T]} */
					(
						removeOperations(
							/** @type {T} */
							(value),
							keysToKeepOriginalValue
						)
					);
				break;
			case VALUE_TYPE_ARRAY_EXTEND:
				newObj[key] =
					/** @type {T[keyof T]} */
					(
						/** @type {EXPECTED_ANY[]} */
						(value).filter(i => i !== "...")
					);
				break;
			default:
				newObj[key] = value;
				break;
		}
	}
	return newObj;
}
@template {object} T
@param {T} obj the object
@param {(keyof T)[]=} keysToKeepOriginalValue keys to keep original value
@returns {T} the object without operations like "..." or DELETE