代码之家  ›  专栏  ›  技术社区  ›  Alexander Zeitler

基于接口的类方法实现

  •  0
  • Alexander Zeitler  · 技术社区  · 5 年前

    鉴于此 interface 从第三方库类型定义:

    interface IHttpResponse<T> {
      data: T;
      status: number;
      headers: IHttpHeadersGetter;
      config: IRequestConfig;
      statusText: string;
      xhrStatus: 'complete' | 'error' | 'timeout' | 'abort';
    }
    

    具有 IHttpHeadersGetter 因为:

    interface IHttpHeadersGetter {
      (): { [name: string]: string; };
      (headerName: string): string;
    }
    

    我如何实现 headers 在一个 class 那个 implements IHttpResponse<T> 是吗?

    这就是我的 实现看起来像,但可以看出,并非所有成员都来自 IHTTpheadersGetter阅读器 实施:

    class MockResponse<T> implements IHttpResponse<T> {
      data: T;  
      status: number;
      headers (headerName: string): string {
        // return some header value
      };
      config: IRequestConfig;
      statusText: string;
      xhrStatus: "complete" | "error" | "timeout" | "abort";
    }
    

    因此, tsc 对此抱怨:

    error TS2345: Argument of type 'MockResponse<any>' is not assignable to parameter of type 'IHttpResponse<any>'.
      Types of property 'headers' are incompatible.
        Type '(headerName: string) => string' is not assignable to type 'IHttpHeadersGetter'.
    

    我该如何实施 标题 正确地?

    2 回复  |  直到 5 年前
        1
  •  2
  •   jcalz    5 年前

    类型 IHttpHeadersGetter 有两个呼叫签名。也就是说这是一个 overloaded function ,它的任何实现都需要兼容。做到这一点的最简单的方法是使实现本身成为一个重载函数,具有相同的调用签名。 IHTTpheadersGetter阅读器 是的。

    例如(不包括其他属性):

    class MockResponse<T> implements IHttpResponse<T> {
    
        // CALL SIGNATURES
        headers(): { [name: string]: string }; // call signature 1
        headers(headerName: string): string; // call signature 2
    
        // IMPLEMENTATION
        headers(headerName?: string): string | { [name: string]: string } {
            const theHeaders: { [name: string]: string } = {
                someHeader: "hello",
                otherHeader: "you"
            }
            return (typeof headerName !== "string") ? theHeaders :
                (headerName in theHeaders) ? theHeaders[headerName] : "";
        };
    }
    

    这应该为您编译并按需要工作。希望有帮助,祝你好运!

    Link to code

        2
  •  1
  •   GregL    5 年前

    关键部分是定义 headers 函数,然后使用两个重载组合的类型签名实现实际方法。

    最后一堂课应该是:

    class MockResponse<T> implements IHttpResponse<T> {
      data: T;  
      status: number;
      // specify the two overloads first
      headers(): { [name: string]: string; };
      headers(headerName: string): string;
      // then implement the method combining both signatures
      headers (headerName?: string): string | { [name: string]: string; } {
        // return some header value
        if (typeof headerName === 'string') {
          return headerName;
        }
        return { some: 'object' };
      };
      config: IRequestConfig;
      statusText: string;
      xhrStatus: "complete" | "error" | "timeout" | "abort";
    }
    

    穿上它 typescriptlang.org playground 是的。