我必须开始展示我的代码才能解释我的问题。
我的通用类:
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有一个通用约束,我希望我能够在publisherRequest属性上调用toBuffer()
,但显然我不是。
我试图解决这个问题:
我认为这可能是因为RpcPublisherMessage<any>
中的任何一个也可能需要给出约束,但函数参数中的rpcMessage: RpcPublisherMessage<any extends RpcPublisherRequest<any>>
之类的东西却没有用。然后VSCode说
[ts]来自导出类的公共方法的参数'rpcMessage'具有 或使用私人名称''。
我的问题:
为什么即使我为此属性指定了约束,我也无法在toBuffer()
上调用publisherRequest
?
答案 0 :(得分:1)
阐述我的评论作为答案。
除此之外:以下定义
export class RpcPublisherMessage<T extends RpcPublisherRequest<T>> { ... }
不是你想说的。从字面上看,您说参数T
应该可以分配给RpcPublisherRequest<T>
,其中第二个T
与第一个T
相同payload
。除非您希望RpcPublisherRequest
的{{1}}为RpcPublisherMessage
,publisherRequest
类型为RpcPublisherRequest
,其payload
为RpcPublisherMessage
} publisherRequest
是......:颤抖:除非你真的想要T
的递归类型绑定,否则你应该改变那个定义。
如果你想要的是T
应该是某些 RpcPublisherRequest<U>
的{{1}},那么你就可以做到这一点:
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()
,这很糟糕。并且您没有获得IntelliSense建议方法,因为toButter()
类型可以具有任何属性,这是不好的。
这是因为any
指定RpcPublisherMessage<any>
是T
,它符合所有约束但不会给你任何类型提示。如果您想要更严格的约束,则可以指定any
为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
}
是您的通用有效负载类型。但你可能不需要那么远。
好的希望有所帮助;祝你好运!