打字稿方法泛型参数和返回类型

时间:2021-03-29 10:42:23

标签: typescript generics

我在理解泛型的工作原理方面遇到了一些麻烦。我已经阅读了 Typescript 手册,这应该有效,但它没有......

我有这样的界面:

interface IApi {
  request<T>( config: BaseRequest<T> ): Promise<T>;
}

请求类型为一个获取物品的请求:

export abstract class BaseRequest<T = any> {
  public readonly descriptor: IRequestDescriptor;
  constructor( descriptor: IRequestDescriptor, accessTokenRequired: boolean = true ) {
    this.descriptor = { ...descriptor, accessTokenRequired: accessTokenRequired };
  }
}

class GetItemRequest extends BaseRequest<{ item: string }> {
  constructor(
    itemId: number,
  ) {

    super( {
      method: 'GET',
      url: `/item/${itemId}`,
      responseType: 'json',
    } );
  }
}

现在,当我尝试使用 GetItemRequest 时,我想这样做:

api.request( new GetItemRequest( 1 ) )
  .then( (response) => {
    // here response should be of type: { item: string } but it isn't
})

但是当我这样称呼它时:

api.request<{ item: string }>( new GetItemRequest( 1 ) )
  .then( (response) => {
    // here response is typed as expected: { item: string }
})

所以我的目标是在调用 request 方法期间而不是在请求对象中放入有关响应类型的信息。但出于某种原因,我无法做到这一点。上面的代码有什么问题?这些通用信息只是 Typescript 的一个提示。 BaseRequest<T = any> 的实现中根本不使用泛型类型。

更新

我找到了解决方法。我只需要它在 BaseRequest 的实现中至少在一个地方使用泛型类型,因此当我为此更改其实现时,它会按预期工作。

export abstract class BaseRequest<ResponseType = any> {
  public readonly descriptor: IRequestDescriptor;
  private readonly _responseType?: ResponseType; // it is used only response type for type help

  constructor( descriptor: IRequestDescriptor, accessTokenRequired: boolean = true ) {
    this.descriptor = { ...descriptor, accessTokenRequired: accessTokenRequired };
  }
}

所以我添加了 _responseType 可选变量,该变量从未在实现中使用,但它使 typescript 泛型现在按预期工作。没有这个可选属性,有什么办法可以做到吗?

0 个答案:

没有答案