// 获取函数的返回类型 type GetArgType = T extends (arg: infer AT) => any ? AT : never // 获取函数的返回类型 type GetReturnType = T extends (...args: any[]) => infer RT ? RT : never type IFCommon = { /** 是上传文件接口 */ isUpload?: boolean } // 接口信息 interface IFConfig extends IFCommon { realUrl: string /** * 接口请求参数类型 */ reqType?: QT /** * 接口请求参数类型 */ resType?: ST } /** * 返回安全类型 * NT 新类型 * OT 旧类型 * 权重:新类型>旧类型,权重高的有值则使用 */ // (OT extends never ? any : OT) // type GetSAST = unknown extends NT ? OT : NT // /** 合并两个类型,新类型覆盖旧类型 */ // type MergeType = NT extends AnyObject ? MergeObjectType : NT // /** 合并两个对象类型,新类型覆盖旧类型的子属性 */ // type MergeObjectType = { // [P in keyof (OT & NT)]: P extends keyof NT ? MergeType : OT[P] // } /** 两个类型完全相等 */ type IsEqual = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? true : false // X extends Y ? (Y extends X ? true : false) : false /** 合并子属性 */ type MargeSub = { [P in keyof NT]: SafeMarge } /** 安全合并: * NT为any类型使用OT, * NT为对象进行合并,删除(OT)旧类型的((NT)新类型的属性)属性 & (NT)新类型, * NT为一般类型使用NT */ type SafeMarge = IsEqual extends true ? OT : NT extends AnyObject ? Omit & MargeSub : NT /** 未设置NT使用OT */ type SwitchType = NT extends null ? OT : SafeMarge> // Omit 是重点!!! 可以巧妙的避免其作为入参类型时的自动推导 /** 请求方法 */ type RequestFunc = ( args?: SwitchType, options?: IRequestExt, ) => PromiseExt> /** * 接口的服务类型 * @generic ST:接口配置的resType类型,接口返回值类型 * @generic QT:接口配置的reqType类型,接口请求参数类型 */ interface IServiceApi { /** * get 请求 * @generic Q:对入参类型的修饰,传null不进行修饰 * @generic S:对出参类型的修饰,传null不进行修饰 */ get: RequestFunc /** * post 请求 * @generic Q:对入参类型的修饰,传null不进行修饰 * @generic S:对出参类型的修饰,传null不进行修饰 */ post: RequestFunc // post: (args?: Q, options?: IRequestOption) => PromiseExt } /** 扩展Promise定义 */ interface PromiseExt { then(onfulfilled?: (value: T) => void | undefined | null): PromiseExt catch(onrejected?: ((reason: TPromiseCatchReason) => void) | undefined | null): PromiseExt } /** catch回调函数入参 */ interface TPromiseCatchReason { /** 错误类型 enums.ErrorType */ errType: number /** 公共请求入参 */ options: IRequestOption /** 业务异常信息 */ res?: IResData /** 通讯异常信息 */ errInfo?: UniApp.RequestSuccessCallbackResult } /** 接口信息 */ type IWebApi = { /** * 接口名称 */ name: string /** * 动态获取接口当前地址 * @returns */ getUrl: () => string /** * 当前接口分组 */ group: string } & IFCommon /** 公共请求入参 */ type IRequestOption = { /** 接口信息 */ urlObj?: IWebApi /** UniApp请求入参合集 */ uur: UUR /** 扩展参数 */ ext: IRequestExt } /** UniApp请求入参合集 */ interface UUR extends UniApp.RequestOptions, UniApp.UploadFileOption { url?: string } /** 请求的扩展参数 */ interface IRequestExt { /** 显示loading效果 */ showLoading?: boolean /** loading文案 */ loadingText?: string /** 上传文件选择的文件列表 */ choosFiles?: string[] /** 最多可以选择的文件个数,默认1 */ fileCount?: number /** 追加url */ appendUrl?: string /** 最小请求时长 ms */ minRTime?: number /** 临时记录请求时间戳 ms */ _tempRtimespan?: number } /** 分页返回数据 */ type IPage = { /** 当前页 */ current?: number /** 总页数 */ pages?: number /** 总条数 */ total?: number /** 数据集合 */ records?: Array } /** 分页请求参数 */ interface IPageParams { /** 当前页面 */ page: number /** 数据量 */ size: number /** 请求的参数 */ param: T } /** 接口统一返回结构 */ type IResData = { code: number message: string data: T }