/**
 *
 * @param obj - El objeto a evaluar.
 * @template T - El tipo del objeto.
 * @description Verifica si un objeto no tiene campos con valor undefined.
 *
 * Esta función recorre los valores del objeto y devuelve true si todos los valores son diferentes de undefined.
 * Si al menos un valor es undefined, devuelve false.
 *
 * @example
 * const obj = { a: 1, b: 'test', c: null };
 * console.log(hasNoUndefinedFields(obj)); // true
 *
 * const objWithUndefined = { a: 1, b: undefined, c: null };
 * console.log(hasNoUndefinedFields(objWithUndefined)); // false
 *
 * @template T - El tipo del objeto.
 * @param obj - El objeto a evaluar.
 * @returns true si el objeto no tiene campos undefined, false en caso contrario.
 */

export function hasNoUndefinedFields<T extends Record<string, unknown>>(
  obj: T
): obj is { [K in keyof T]-?: Exclude<T[K], undefined> } {
  return Object.values(obj).every((value) => value !== undefined);
}

/**
 *
 * @description Verifica si un objeto tiene campos con valor undefined.
 * Esta función es el complemento de `hasNoUndefinedFields`.
 *
 * @example
 * const obj = { a: 1, b: 'test', c: null };
 * console.log(hasUndefinedFields(obj)); // false
 *
 * const objWithUndefined = { a: 1, b: undefined, c: null };
 * console.log(hasUndefinedFields(objWithUndefined)); // true
 *
 * @template T - El tipo del objeto.
 * @param obj - El objeto a evaluar.
 * @returns true si el objeto tiene al menos un campo undefined, false en caso contrario.
 *
 */

export function hasUndefinedFields<T extends Record<string, unknown>>(
  obj: T
): obj is { [K in keyof T]-?: Exclude<T[K], undefined> } {
  return !hasNoUndefinedFields(obj);
}
