/**
 * Property Override Detection Utilities
 *
 * Provides utilities for detecting explicitly provided property values and merging
 * user props with framework defaults. These utilities are essential for the
 * declarative CDK API to correctly handle the override pattern.
 *
 * Key distinction: undefined vs falsy values
 * - `undefined` means "not provided" → use framework default
 * - Falsy values (false, 0, '', null) mean "explicitly provided" → preserve user value
 *
 * This distinction is critical for CDK props where users may intentionally set:
 * - `false` to disable a feature (e.g., versioned: false)
 * - `0` for numeric settings (e.g., retentionDays: 0)
 * - `''` for empty strings (e.g., prefix: '')
 * - `null` to explicitly unset a value
 *
 * @module prop-override-utils
 * @see Requirements 2.6, 2.7 in declarative-cdk-api-refactor spec
 */
/**
 * Checks if a property was explicitly provided (not undefined).
 *
 * This function uses strict undefined checking to correctly handle falsy values.
 * A value is considered "explicitly provided" if it is anything other than `undefined`.
 *
 * @typeParam T - The type of the value being checked
 * @param value - The value to check, which may be undefined
 * @returns Type guard indicating whether the value was explicitly provided
 *
 * @example
 * // Falsy values are considered explicit
 * isExplicitlyProvided(false)  // true - user explicitly set false
 * isExplicitlyProvided(0)      // true - user explicitly set 0
 * isExplicitlyProvided('')     // true - user explicitly set empty string
 * isExplicitlyProvided(null)   // true - user explicitly set null
 *
 * @example
 * // Only undefined is considered "not provided"
 * isExplicitlyProvided(undefined)  // false - use framework default
 *
 * @example
 * // Truthy values are explicit
 * isExplicitlyProvided('value')    // true
 * isExplicitlyProvided(42)         // true
 * isExplicitlyProvided({ key: 1 }) // true
 *
 * @remarks
 * This function is a type guard that narrows `T | undefined` to `T`.
 * After calling this function with a truthy result, TypeScript knows
 * the value is not undefined.
 *
 * @see Requirement 2.7 - Override detection SHALL use explicit undefined checks
 *                        rather than truthiness checks to support falsy values
 */
export declare function isExplicitlyProvided<T>(value: T | undefined): value is T;
/**
 * Merges user props with framework defaults, respecting explicit values.
 *
 * User-provided values (including falsy ones like false, 0, '', null) take
 * precedence over framework defaults. Only properties that are `undefined`
 * in userProps will use the default value.
 *
 * @typeParam TProps - The props object type (must be an object)
 * @param userProps - User-provided props (may contain undefined values)
 * @param defaults - Framework default values for props
 * @returns Merged props object with user values taking precedence
 *
 * @example
 * // User explicitly sets versioned to false
 * const result = mergeWithDefaults(
 *   { bucketName: 'my-bucket', versioned: false },
 *   { versioned: true, encryption: 'S3_MANAGED' }
 * );
 * // Result: { bucketName: 'my-bucket', versioned: false, encryption: 'S3_MANAGED' }
 * // Note: versioned is false (user value), not true (default)
 *
 * @example
 * // User doesn't provide removalPolicy, so default applies
 * const result = mergeWithDefaults(
 *   { tableName: 'my-table' },
 *   { removalPolicy: 'DESTROY', pointInTimeRecovery: true }
 * );
 * // Result: { tableName: 'my-table', removalPolicy: 'DESTROY', pointInTimeRecovery: true }
 *
 * @example
 * // User explicitly sets numeric value to 0
 * const result = mergeWithDefaults(
 *   { retentionDays: 0 },
 *   { retentionDays: 30 }
 * );
 * // Result: { retentionDays: 0 }
 * // Note: 0 is preserved, not replaced with 30
 *
 * @remarks
 * The merge algorithm:
 * 1. Start with a copy of defaults
 * 2. For each key in userProps, if the value is not undefined, use it
 * 3. Return the merged result
 *
 * This ensures that:
 * - Undefined user props get default values
 * - Explicitly provided user props (including falsy) override defaults
 * - Properties only in defaults are preserved
 * - Properties only in userProps are included
 *
 * @see Requirement 2.6 - IF a prop is undefined in user-provided props,
 *                        THEN apply the framework default for that prop
 * @see Requirement 2.7 - Override detection SHALL use explicit undefined checks
 */
export declare function mergeWithDefaults<TProps extends object>(userProps: TProps, defaults: Partial<TProps>): TProps;
/**
 * Creates a props object with only explicitly provided values.
 *
 * This utility filters out undefined values from a props object,
 * useful when you need to pass only the explicitly set props to a CDK construct.
 *
 * @typeParam TProps - The props object type (must be an object)
 * @param props - Props object that may contain undefined values
 * @returns New object containing only explicitly provided (non-undefined) values
 *
 * @example
 * const input = { name: 'test', value: undefined, count: 0 };
 * const result = filterExplicitProps(input);
 * // Result: { name: 'test', count: 0 }
 * // Note: undefined is removed, but 0 is preserved
 *
 * @remarks
 * This is useful when spreading props to CDK constructs where you want
 * to avoid passing undefined values that might override CDK's own defaults.
 */
export declare function filterExplicitProps<TProps extends object>(props: TProps): Partial<TProps>;
