/**
 * Checks if an object has a property of a specific type
 *
 * @param obj - The object to check
 * @param prop - The property name to check
 * @param type - The expected type of the property
 * @param isOptional - Whether the property is optional (defaults to false)
 *
 * @returns boolean indicating if the object has the property of the specified type
 */
export const hasPropertyOfType = <T extends object>(
  obj: unknown,
  prop: keyof T,
  type: 'string' | 'number' | 'boolean' | 'object' | 'array',
  isOptional: boolean = false,
): obj is T => {
  try {
    if (obj == null || typeof obj !== 'object') {
      return false;
    }

    // If property is not present, it's valid for an optional property
    if (!(prop in obj)) {
      return isOptional;
    }

    const value = (obj as T)[prop];

    // For optional properties, null or undefined values are valid
    if (isOptional && value == null) {
      return true;
    }

    if (type === 'array') {
      return Array.isArray(value);
    }

    return typeof value === type;
  } catch (err) {
    // swallow the error as it should be reported in more detail by the caller
    return false;
  }
};
