我尝试写一个消息订阅函数的等价物。一个没有类型的简化版本看起来像这样:
function newMessage(message) {
postMessage(message)
}
function subscribe(messageType, callback) {
handleNewMessage(message => {
if (message.type === messageType) {
callback(message.data)
}
})
}
newMessage
的message
可以是多个类型,因此我分别定义它们,然后使用区分联合来输入message
参数。
type FooMessage = {
type: 'foo',
data: {
a: string,
b: number
}
}
type BarMessage = {
type: 'bar'
}
type MessageType = FooMessage | BarMessage
请注意BarMessage
没有任何关联的数据。
这允许我的newMessage
函数被键入如下:
function newMessage(message:MessageType):void {
postMessage(message)
}
不过我不完全确定如何输入subscribe
。这是我目前所拥有的:
function subscribe(messageType: MessageType['type'], callback) {
handleNewMessage(message => {
if (message.type === messageType) {
callback(message.data)
}
})
}
我不确定如何输入callback
。如果我输入MessageType['data']
,我会得到一个错误,因为data
并不总是存在。即使我在BarMessage
上定义了data:undefined
,我也失去了消息类型和数据之间的链接。
理想情况下,我希望能够编写subscribe('bar', (data) => console.log(data))
和typescript,以了解data
在本例中实际上是未定义的。
我可以看到的一个选项是为我拥有的每个消息类型多次声明一个函数类型,但这感觉过于冗长,因为这意味着对于每个消息类型,我都要定义MessageType
和关联的subscribe函数。
在现实中,我有很多很多更多的消息,并不希望这样做。
键入subscribe
的callback
函数的最佳方法是什么?
1条答案
按热度按时间owfi6suc1#
您可以使用下列项目:
T
,以便TypeScript可以缩小消息类型(如果它是静态已知的)Extract
的分布式条件类型,它允许缩小到分布式联合的特定成员类型,有关详细信息,请参见this SO threaddata
的类型作为关键字存在时,才从消息中提取该类型这里是一个Playground链接TypeScriptPlayground