lei-mu / luch-request

luch-request 是一个基于Promise 开发的uni-app跨平台、项目级别的请求库,它有更小的体积,易用的api,方便简单的自定义能力。
https://www.quanzhan.co/luch-request/
MIT License
632 stars 96 forks source link

ts声明文件中方法返回值类型写死了,跟响应拦截器的返回值有冲突 #86

Open fjxfirst opened 2 years ago

fjxfirst commented 2 years ago

get<T = any>(url: string, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;

export interface HttpResponse<T = any> {
  config: HttpRequestConfig;
  statusCode: number;
  cookies: Array<string>;
  data: T;
  errMsg: string;
  header: AnyObject;
}

get方法的返回值类型也有可能是经过响应拦截器之后确定的,开发者往往不希望从封装HttpResponse结构中再次通过点运算符获取data,而是希望直接返回data,所以返回值HttpPromise写死不太灵活,这个有解决办法吗?

ModyQyW commented 2 years ago

https://github.com/lei-mu/luch-request/pull/44 可能有用,但作者还没发布,可能都忘了😅

fjxfirst commented 2 years ago

暂时用declare module解决了

declare module 'luch-request' {
  export type HttpTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask;

  export type HttpRequestTask = UniApp.RequestTask;

  export type HttpUploadTask = UniApp.UploadTask;

  export type HttpDownloadTask = UniApp.DownloadTask;

  export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "CONNECT" | "HEAD" | "OPTIONS" | "TRACE" | "UPLOAD" | "DOWNLOAD";

  export type HttpRequestHeader = Record<string, string>;

  export type HttpParams = Record<string, any>;

  export type HttpData = Record<string, any>;

  export type HttpResponseType = 'arraybuffer' | 'text';

  export type HttpCustom = Record<string, any>;

  export type HttpFileType = 'image' | 'video' | 'audio';

  export type HttpFormData = Record<string, any>;

  export type HttpResponseHeader = Record<string, string> & {
    "set-cookie"?: string[]
  };

  export interface HttpRequestConfig<T = HttpTask> {
    /** @desc 请求服务器接口地址 */
    url?: string;
    /** @desc 请求方式,默认为 GET */
    method?: HttpMethod;
    /** @desc 请求基地址 */
    baseURL?: string;
    /** @desc 请求头信息,不能设置 Referer,App、H5 端会自动带上 cookie,且 H5 端不可手动修改 */
    header?: HttpRequestHeader;
    /** @desc 请求查询参数,自动拼接为查询字符串 */
    params?: HttpParams;
    /** @desc 请求体参数 */
    data?: HttpData;
    /** @desc 超时时间,单位 ms,默认为 60000,仅 H5 (HBuilderX 2.9.9+)、APP (HBuilderX 2.9.9+)、微信小程序 (2.10.0)、支付宝小程序支持 */
    timeout?: number;
    /** @desc 跨域请求时是否携带凭证 (cookies),默认为 false,仅 H5 (HBuilderX 2.6.15+) 支持 */
    withCredentials?: boolean;
    /** @desc 设置响应的数据类型,支付宝小程序不支持 */
    responseType?: HttpResponseType;
    /** @desc 全局自定义验证器 */
    validateStatus?: ((statusCode: number) => boolean) | null;

    /** @desc 默认为 json,如果设为 json,会尝试对返回的数据做一次 JSON.parse */
    dataType?: string;
    /** @desc DNS 解析时是否优先使用 ipv4,默认为 false,仅 App-Android (HBuilderX 2.8.0+) 支持 */
    firstIpv4?: boolean;
    /** @desc 是否验证 SSL 证书,默认为 true,仅 App-Android (HBuilderX 2.3.3+) 支持 */
    sslVerify?: boolean;

    /** @desc 自定义参数 */
    custom?: HttpCustom;

    /** @desc 返回当前请求的 task 和 options,不要在这里修改 options */
    getTask?: (task: T, options: HttpRequestConfig<T>) => void;

    /** @desc 需要上传的文件列表,使用 files 时,filePath 和 name 不生效,仅支持 App、H5 (2.6.15+) */
    files?: { name?: string; file?: File; uri: string; }[];
    /** @desc 文件类型,仅支付宝小程序支持且为必填项 */
    fileType?: HttpFileType;
    /** @desc 要上传的文件对象,仅 H5 (2.6.15+) 支持 */
    file?: File;
    /** @desc 要上传文件资源的路径,使用 files 时,filePath 和 name 不生效 */
    filePath?: string;
    /** @desc 文件对应的 key,开发者在服务器端通过这个 key 可以获取到文件二进制内容,使用 files 时,filePath 和 name 不生效 */
    name?: string;
    /** @desc 请求中其他额外的 form data */
    formData?: HttpFormData;
  }

  export interface HttpResponse<T = any, D = HttpTask>  {
    data: T;
    statusCode: number;
    header: HttpResponseHeader;
    config: HttpRequestConfig<D>;
    cookies: string[];
    errMsg: string;
  }

  export interface HttpUploadResponse<T = any, D = HttpTask> {
    data: T;
    statusCode: number;
    config: HttpRequestConfig<D>;
    errMsg: string;
  }

  export interface HttpDownloadResponse extends HttpResponse {
    tempFilePath: string;
  }

  export interface HttpError<T = any, D = HttpTask> {
    data?: T;
    statusCode?: number;
    header?: HttpResponseHeader;
    config: HttpRequestConfig<D>;
    cookies?: string[];
    errMsg: string;
  }

  export interface HttpPromise<T = any> extends Promise<HttpResponse<T>> {}

  export interface HttpInterceptorManager<V, E = V> {
    use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: E) => E | Promise<E>): void;
    eject(id: number): void;
  }

  export abstract class HttpRequestAbstract {
    constructor(config?: HttpRequestConfig);
    interceptors: {
      request: HttpInterceptorManager<HttpRequestConfig>;
      response: HttpInterceptorManager<HttpResponse, HttpError>;
    }
    request<T = any, R = HttpResponse<T>, D = HttpRequestTask>(config: HttpRequestConfig<D>): Promise<R>;
    get<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
    delete<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
    head<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
    options<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
    post<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
    put<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;

    config: HttpRequestConfig;
    setConfig<D = HttpTask>(onSend: (config: HttpRequestConfig<D>) => HttpRequestConfig<D>): void;
    connect<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
    trace<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
    upload<T = any, R = HttpUploadResponse<T>, D = HttpUploadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
    download<T = any, R = HttpDownloadResponse, D = HttpDownloadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
    middleware<T = any, R = HttpResponse<T>, D = HttpTask>(config: HttpRequestConfig<D>): Promise<R>;
  }

  class HttpRequest extends HttpRequestAbstract {}
  export default HttpRequest;
}
obstrux commented 1 year ago

可以用patch解决一下