我正在尝试创建消息总线API,该消息中的消息只能与特定类型/形状的有效载荷一起发送。
我基本上是在这样做,以便当我开始键入对emitMessage
的调用(如下)时,我希望IDE能够为{{1}提供编译时类型提示。 }参数一旦指定了payload
,就可以知道任何给定消息类型期望使用哪种type
。
我已经尝试过以下操作:
payload
但是该代码不完整/不正确,因为我不知道如何指定// I create some generic payload interface that can be any shape
interface Payload<T> {
[key: string]: any
}
// I define an enum of permitted message types
enum MessageType {
TEST
}
// And then I expose a function for emitting messages of a particular type
// along with its associated payload
function emitMessage<Msg extends MessageType>(type: Msg, payload: Payload<Msg>) {
// ...
}
枚举的特定变体与MessageType
的特定专业化相关。
我不确定这是否可能,因此,对此方向的任何帮助将不胜感激。
答案 0 :(得分:0)
我发现了this script形式的非常酷的解决方案
// I define an enum of permitted message types
enum MessageType {
TEST
}
// This interface is then used as a kind of "type directory"
interface Payload {
[MessageType.TEST]: {
test: boolean
}
}
// payload's type here is now an index into the Payload type directory
function emitMessage<M extends MessageType>(msg: M, payload: Payload[M]) {
switch(msg) {
case MessageType.TEST: {
// payload.test is suggested by my IDE now!
}
}
}
此功能很棒,我想将其用于所有功能
答案 1 :(得分:0)
一种方法是使用有区别的联合。首先在您的有效负载中添加一个字段,以指示其类型,例如kind
beliow
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
首先,我们声明要合并的接口。每个接口都有一个具有不同字符串文字类型的kind属性。 kind属性称为判别式或标记。其他属性特定于每个接口。请注意,接口当前不相关。让我们将它们组成一个联合体:
type Shape = Square | Rectangle | Circle;
现在让我们使用有区别的联合:
function area(s: Shape) {
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.height * s.width;
case "circle": return Math.PI * s.radius ** 2;
}
}