我在理解泛型的工作原理方面遇到了一些麻烦。我已经阅读了 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 泛型现在按预期工作。没有这个可选属性,有什么办法可以做到吗?