繁体   English   中英

任何类型的通用约束

[英]Generic constraint with any type

我必须开始显示我的代码才能解释我的问题。

我的通用类:

export class RpcPublisherMessage<T extends RpcPublisherRequest<T>> {
  constructor(public publisherRequest: T, public publishOptions: Options.Publish = {}, public timeoutMs?: number) {}
}

export class RpcPublisherRequest<T> extends RpcMessageData<T> {
  constructor(payload: T, private context: string) {
    super(payload);
  }

  public toBuffer(): Buffer {
    return Buffer.from(...);
  }
}

我的问题:

  public async dispatchMessage(rpcMessage: RpcPublisherMessage<any>): Promise<IRequestMessageResponse> {
    const message = rpcMessage.publisherRequest; // I can not call toBuffer() here
  }

这是我要使用RpcPublisherMessage<any>实例的RpcPublisherMessage<any> 由于RpcPublishermessage具有通用约束,所以我希望能够在PublisherRequest属性上调用toBuffer() ,但显然不能。

我试图解决的问题:

我认为可能是因为RpcPublisherMessage<any>中的RpcPublisherMessage<any>可能还需要给定约束,但是类似rpcMessage: RpcPublisherMessage<any extends RpcPublisherRequest<any>>东西rpcMessage: RpcPublisherMessage<any extends RpcPublisherRequest<any>>的功能参数无效。 VSCode然后说

[ts]导出类的公共方法的参数'rpcMessage'具有或正在使用私有名称”。

我的问题:

为什么我不能够调用toBuffer()publisherRequest即使我指定该物业的约束?

详细阐述我的评论作为答案。


撇开:以下定义

export class RpcPublisherMessage<T extends RpcPublisherRequest<T>> { ... }

不是你想说的 从字面上看,您说的是参数T应该可分配给RpcPublisherRequest<T> ,其中第二个T 与第一个T相同 除非你想的payload的的RpcPublisherRequest是一个RpcPublisherMessagepublisherRequest类型是RpcPublisherRequest ,其payloadRpcPublisherMessagepublisherRequest是...:颤抖:除非你真的想开往递归式T ,你应该改变这个定义。

如果你想要的是T应该是一个RpcPublisherRequest<U>对于一些 U ,那么你就可以这样做脱身:

export class RpcPublisherMessage<T extends RpcPublisherRequest<any>> { ... }

这不再是递归类型绑定。


主:这个问题

public async dispatchMessage(
  rpcMessage: RpcPublisherMessage<any>
): Promise<IRequestMessageResponse> {
  const message = rpcMessage.publisherRequest.toBuffer(); // no error
  const massage = rpcMessage.publisherRequest.toButter(); // also no error
}

不应是您不能调用toBuffer() 相反,问题在于rpcMessage.publisherRequest的类型为any ,这意味着您可以在不抱怨的情况下调用toBuffer() 但是您也可以不加抱怨地调用toButter() ,这很糟糕。 而且您不会获得IntelliSense建议方法,因为any类型都可以具有任何属性,这很糟糕。

这是因为RpcPublisherMessage<any>指定Tany ,它满足所有约束但不提供任何类型提示。 如果想要更严格的约束,可以将T指定为RpcPublisherRequest<any>

public async dispatchMessage(
  rpcMessage: RpcPublisherMessage<RpcPublisherRequest<any>>
): Promise<IRequestMessageResponse> {
  const message = rpcMessage.publisherRequest.toBuffer(); // no error
  const massage = rpcMessage.publisherRequest.toButter(); // error, yay!
}

那应该解决您的问题。 如果您需要跟踪请求类型的特定有效负载类型,则可以始终使dispatchMessage()为通用方法,如下所示:

public async dispatchMessage<P>(
  rpcMessage: RpcPublisherMessage<RpcPublisherRequest<P>>
): Promise<IRequestMessageResponse> {
  const message = rpcMessage.publisherRequest.toBuffer(); // no error
}

其中P是您的通用有效载荷类型。 但是您可能不需要走那么远。


好的,希望能有所帮助; 祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM