首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >泛型类方法与泛型类的类型文本语义差异

泛型类方法与泛型类的类型文本语义差异
EN

Stack Overflow用户
提问于 2018-08-14 06:12:31
回答 1查看 51关注 0票数 0

当我使用类泛型时,而当我使用方法泛型时,下面的示例代码为什么会工作,我有点困惑。

首先,我有一些简单的RequestResponse类:

代码语言:javascript
复制
abstract class BaseRequest {
  baseProperty: string;
}

class ChildRequest extends BaseRequest {
  childProperty: string;
}

abstract class BaseResponse<R extends BaseRequest> {
  data: any;
  request: R;
}

class ChildResponse extends BaseResponse<ChildRequest> {
}

为了保持继承的简单性,希望使用下面的泛型方法代码(注意类不是泛型的,只有方法和扩展基类不需要泛型):

代码语言:javascript
复制
abstract class RequestClient {
  abstract request<RQ extends BaseRequest, RP extends BaseResponse<RQ>>(request: RQ): RP;
}


class ChildClient extends RequestClient {
  request(request: ChildRequest): ChildResponse {
    return undefined;   // just testing the code structure right now
  }
}

但是编译器是在ChildClient.request上完成的

代码语言:javascript
复制
TS2416: Property 'request' in type 'ChildClient' is not assignable to the same property in base type 'RequestClient'.
  Type '(request: ChildRequest) => ChildResponse' is not assignable to type '<RQ extends BaseRequest, RP extends BaseResponse<RQ>>(request: RQ) => RP'.
    Types of parameters 'request' and 'request' are incompatible.
      Type 'RQ' is not assignable to type 'ChildRequest'.
        Type 'BaseRequest' is not assignable to type 'ChildRequest'.
          Property 'childProperty' is missing in type 'BaseRequest'.

但是,使用类泛型很好:

代码语言:javascript
复制
abstract class RequestClient<RQ extends BaseRequest, RP extends BaseResponse<RQ>> {
  abstract request(request: RQ): RP;
}

class ChildClient extends RequestClient<ChildRequest, ChildResponse> {
  request(request: ChildRequest): ChildResponse {
    return undefined;
  }
}

我想避免类泛型,因为它开始创建类继承、涓滴爆炸,在那里,我有大量无用的子类,只是为了正确编译泛型方法。

为什么类泛型工作,而不是方法泛型?这里的语义区别是什么?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-14 06:22:30

因为在泛型方法示例中,您的子类违反了基类定义的契约。

基类保证该类的实例允许调用者选择任何类型的请求和响应,但是子类重写请求方法并限制约定:不,我只能发送一个ChildRequest,而您只能得到一个ChildResponse。

考虑以下情况:

代码语言:javascript
复制
const client: RequestClient = new ChildClient();

这是有效的,因为ChildClient扩展了RequestClient。因此,由于客户端是RequestClient,所以您可以

代码语言:javascript
复制
const response: MyResponse = client.request<MyRequest, MyResponse>(new MyRequest());

如果编译器接受了所需的内容,那么将调用哪个方法?会发生什么?

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51834747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档