/**
 * 把一个对象T的值统一替换为K类型
 */
type $ReplaceType<T extends Record<string, unknown>, K> = {
  [P in keyof T]: K;
};

/**
 * 给对象的每一个元素添加一个或多个新的类型
 */
type $AddNewType<T extends Record<string, unknown>, K> = {
  [key in keyof T]: K | T[key];
};

/**
 * 提取Promise函数中返回值的类型
 */
type $UnwrapPromise<T> = T extends (...args: any[]) => Promise<infer U> ? U : T;

/**
 * 提取数组中每一项的类型组成联合类型
 */
type $UnwrapArray<T> = T extends Array<infer U> ? U : T;

/**
 * 驼峰转蛇形(字符串)
 */
type CamelToSnakeCase<T extends string> = T extends `${infer First}${infer Rest}`
  ? Rest extends Uncapitalize<Rest>
    ? `${Lowercase<First>}${CamelToSnakeCase<Rest>}`
    : `${Lowercase<First>}_${CamelToSnakeCase<Uncapitalize<Rest>>}`
  : T;

/** 驼峰转蛇形(对象的key) */
type CamelToSnakeCasedData<T> = T extends (...args: any[]) => any
  ? T
  : T extends Array<infer U> // 如果是数组，递归处理每个元素
    ? CamelToSnakeCasedData<U>[]
    : T extends Record<number | string | symbol, any> // 如果是对象，递归处理每个键和值
      ? {
          [K in keyof T as CamelToSnakeCase<Extract<K, string>>]: CamelToSnakeCasedData<T[K]>;
        }
      : T;
