/**
 * Type Guards 和基础类型工具模块
 */
/**
 * 判定 val 是否为字符串类型（含 infer）
 *
 * @see https://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string-in-javascript
 * @param val
 */
declare const isStr: (val: unknown) => val is string;
/**
 * 检查 val 是否为非空字符串（含 infer）
 *
 * @param val
 */
declare const notEmptyStr: (val: unknown) => val is string;
/**
 * 判断是否为有效的数字类型
 *
 * @param val
 */
declare const isNumber: (val: unknown) => val is number;
/**
 * 判断是否包含有效的数值
 *
 * - 允许字符串包含数值，如 `"123"`
 * - 允许数字类型，如 `123`
 *
 * @param val
 */
declare const isNumberVal: (val: unknown) => boolean;
/**
 * 将包含有效数值的 val 转换为对应的数字类型，只支持以下情形：
 *
 * - 字符串包含数值，如 `"123"`，转换为 `123`
 * - 数字类型，如 `123`，转换为 `123`
 * - 布尔类型，如 `true`，转换为 `1`，`false` 转换为 `0`
 *
 * @param val
 * @param dft 默认值，仅当 val 为 `null` 或 `undefined` 或 非包含有效数值时生效
 */
declare const toNumber: (val: unknown, dft?: number) => number;
/**
 * 限制 val 在最小值范围内
 *
 * @param val
 * @param {number} min 最小值
 * @param {number} dft 默认值，仅当 val 为 `null` 或 `undefined` 或 非包含有效数值时生效
 */
declare const limitNumberMin: (val: unknown, min: number, dft?: number) => number;
/**
 * 限制 val 在最大值范围内
 * @param val
 * @param max 最大值
 * @param dft 默认值，仅当 val 为 `null` 或 `undefined` 或 非包含有效数值时生效
 */
declare const limitNumberMax: (val: unknown, max: number, dft?: number) => number;
/**
 * 限制 val 在最小值和最大值范围内
 * @param val
 * @param min 最小值
 * @param max 最大值
 * @param dft 默认值，仅当 val 为 `null` 或 `undefined` 或 非包含有效数值时生效
 */
declare const limitNumberMinMax: (val: unknown, min: number, max: number, dft?: number) => number;
/**
 * 数字精度调整，支持 `round`、`ceil`、`floor` 三种类型
 *
 * @see https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/round#%E5%B0%8F%E6%95%B0%E8%88%8D%E5%85%A5
 * @param {"round" | "ceil" | "floor"} type 调整类型
 * @param {number} value
 * @param {number} exp 指数（10的 exp 次方 —— 10 进制位数，0 表示个位，1 表示十位，-1 表示小数点后一位，-2 表示小数点后两位，以此类推）。
 * @returns {number}
 */
declare const decimalAdjust: (type: "round" | "ceil" | "floor", value: number, exp?: number) => number;
declare const round10: (value: number, exp?: number) => number;
declare const floor10: (value: number, exp?: number) => number;
declare const ceil10: (value: number, exp?: number) => number;
/**
 * 计算进度值，返回的结果为一个浮点值，表示进度比例，取值在 0 - 1 之间。
 *
 * @param value
 * @param total
 */
declare const calcProgress: (value: number, total: number) => number;
type RecordObj = Record<string, unknown>;
/**
 * 检查 obj 是否为 Object，结果为真时，推导 obj 为 T 类型
 *
 * - 未指定泛型 T，则 T 默认为 `Record<string, unknown>`
 * - 如果指定泛型 T ，而未传入 fn ，只要 obj 是 Object 即推断 obj 为 T
 * ```ts
 * type TestA = {
 *   name?: string;
 * }
 *
 * if (isInferObj<TestA>(obj)) {
 *   // obj 推断为 TestA
 *   console.log(obj.name || 'noname');
 * }
 * ```
 * - 若果传入了 fn ，则先检查是否 Object，再附加 fn 结果进行推断
 * ```ts
 * type TestB = {
 *   name: string;
 * }
 *
 * if (isInferObj<TestB>(obj, it => typeof it.name === 'string')) {
 *   // obj 推断为 TestB
 *   console.log(obj.name);
 * }
 * ```
 * - 通过传入 `x is T` 的 fn ，可省略指定泛型 T（一般用于复杂的结构判定）
 * ```ts
 * // 由 fn 的结果推导 isInferObj 的 T
 * type WithVersion = {
 *  version: number;
 * };
 *
 * const isWithVersion = (it: WithVersion): it is WithVersion =>
 *   typeof it.version === 'number';
 *
 * const ver1 = { ver: 1 };
 * const ver2 = { version: 2 };
 *
 * if (isInferObj(ver1, isWithVersion)) {
 *   // 不符合
 * }
 *
 * if (isInferObj(ver2, isWithVersion)) {
 *   // ver2 推断为 Version
 *   ver2.version += 1;
 * }
 * ```
 *
 * @param obj 任意类型变量
 * @param fn 断言类型判断函数
 */
declare const isInferObj: <T = RecordObj>(obj: unknown, fn?: (it: T) => boolean) => obj is T;
/**
 * 可能是一个包含错误消息的结构
 */
type ErrLike = {
    message?: string;
    error?: string;
};
/**
 * 判断目标是否是 {@link ErrLike}
 *
 * @param err
 */
declare const isErrLike: (err: unknown) => err is ErrLike;
/**
 * 取回错误消息
 *
 * @param err
 */
declare const errMsg: (err: unknown) => string;
/**
 * 检查值是否为布尔值
 *
 * @param val 任意值
 *
 * @example
 * ```ts
 * if (isBool(value)) {
 *   console.log(value ? 'yes' : 'no');
 * }
 * ```
 */
declare const isBool: (val: unknown) => val is boolean;
/**
 * 检查值是否为 null
 *
 * @param val 任意值
 */
declare const isNull: (val: unknown) => val is null;
/**
 * 检查值是否为 undefined
 *
 * @param val 任意值
 */
declare const isUndefined: (val: unknown) => val is undefined;
/**
 * 检查值是否为 null 或 undefined
 *
 * @param val 任意值
 */
declare const isNil: (val: unknown) => val is null | undefined;
/**
 * 检查值是否不为 null 且不为 undefined
 *
 * @param val 任意值
 *
 * @example
 * ```ts
 * if (isPresent(value)) {
 *   console.log(value);
 * }
 * ```
 */
declare const isPresent: <T>(val: T | null | undefined) => val is T;
/**
 * 检查值是否为一个普通对象（不包括数组、Date、RegExp 等特殊对象）
 *
 * @param val 任意值
 *
 * @example
 * ```ts
 * if (isPlainObj(value)) {
 *   console.log(Object.keys(value));
 * }
 * ```
 */
declare const isPlainObj: <T extends Record<string, unknown> = Record<string, unknown>>(val: unknown) => val is T;
/**
 * 检查值是否为数组
 *
 * @param val 任意值
 */
declare const isAry: <T = unknown>(val: unknown) => val is T[];
/**
 * 检查值是否为非空数组，支持可选的元素类型守卫
 *
 * @param val 任意值
 * @param guard 可选的元素类型守卫
 *
 * @example
 * ```ts
 * if (notEmptyAry(value)) {
 *   console.log(value[0]); // value is unknown[]
 * }
 *
 * if (notEmptyAry(value, isStr)) {
 *   console.log(value[0].toUpperCase()); // value is string[]
 * }
 * ```
 */
declare function notEmptyAry<T = unknown>(val: unknown): val is T[];
declare function notEmptyAry<T>(val: unknown, guard: (item: unknown) => item is T): val is T[];
/**
 * 柯里化的数组类型守卫
 *
 * @param guard 元素类型守卫
 * @returns 数组类型守卫函数
 *
 * @example
 * ```ts
 * const isStrAry = aryGuard(isStr);
 *
 * if (isStrAry(value)) {
 *   // value is string[]
 * }
 *
 * // 配合 and 使用
 * const isNonEmptyStrAry = and(isStrAry, (arr) => arr.length > 0);
 * ```
 */
declare const aryGuard: <T>(guard: (item: unknown) => item is T) => TypeGuard<T[]>;
/**
 * 检查值是否为 Promise
 *
 * @param val 任意值
 *
 * @example
 * ```ts
 * if (isPromise(value)) {
 *   await value;
 * }
 * ```
 */
declare const isPromise: <T = unknown>(val: unknown) => val is Promise<T>;
/**
 * 类型守卫函数类型
 */
type TypeGuard<T = unknown> = (val: unknown) => val is T;
/**
 * 组合守卫（AND）
 *
 * 第一个守卫收窄类型到 T，后续守卫在 T 上做进一步筛选
 *
 * @param guards 第一个为类型守卫，后续为断言函数
 * @returns 组合后的守卫函数
 *
 * @example
 * ```ts
 * const isStrAry = aryGuard(isStr);
 * const isNonEmptyStrAry = and(isStrAry, (arr) => arr.length > 0);
 * ```
 */
declare const and: <T>(...guards: [(val: unknown) => val is T, ...((val: T) => boolean)[]]) => TypeGuard<T>;
/**
 * 从 TypeGuard 提取被守卫的类型
 */
type InferGuard<G> = G extends TypeGuard<infer T> ? T : never;
/**
 * 组合守卫（OR）
 *
 * 任意一个守卫通过即返回 true，自动推断联合类型
 *
 * @param guards 一个或多个守卫函数
 * @returns 组合后的守卫函数
 *
 * @example
 * ```ts
 * const isStrOrNum = or(isStr, isNumber);
 * if (isStrOrNum(value)) {
 *   // value: string | number
 * }
 * ```
 */
declare const or: <G extends [TypeGuard<any>, ...TypeGuard<any>[]]>(...guards: G) => TypeGuard<InferGuard<G[number]>>;
/**
 * 守卫取反（NOT）
 *
 * 返回运行时取反函数。由于 TS 类型系统不支持否定类型，
 * 返回值为 `(val: unknown) => boolean`，不作为类型守卫使用。
 *
 * @param guard 要取反的守卫函数
 * @returns 取反后的判断函数
 *
 * @example
 * ```ts
 * const isNotNull = not(isNull);
 * if (isNotNull(value)) {
 *   // 运行时正确，但不会收窄类型
 * }
 * ```
 */
declare const not: (guard: TypeGuard) => ((val: unknown) => boolean);

export { and, aryGuard, calcProgress, ceil10, decimalAdjust, errMsg, floor10, isAry, isBool, isErrLike, isInferObj, isNil, isNull, isNumber, isNumberVal, isPlainObj, isPresent, isPromise, isStr, isUndefined, limitNumberMax, limitNumberMin, limitNumberMinMax, not, notEmptyAry, notEmptyStr, or, round10, toNumber };
export type { ErrLike, InferGuard, RecordObj, TypeGuard };
