实现基于接口的类方法

时间:2019-10-05 00:44:51

标签: typescript

从第三方库类型定义中获得以下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的{​​{1}}中实现implements

这是我的IHttpResponse<T>实现的样子,但是正如人们所看到的,并不是class的所有成员都得到实现:

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 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

关键部分是在类上定义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上查看。