Reputation: 3410
I'm creating a browser extension and in order to communicate between background and frontend I need to use chrome.runtime.sendMessage()
In my frontend script, I want to send a message to the background, so I do this:
chrome.runtime.sendMessage({ action: 'setUpdate', value: { total: 4, alarm: false } })
And in the background I receive it like this:
chrome.runtime.onMessage.addListener((message: BackgroundMessage) => {
switch (message.action) {
case 'setUpdate':
...
break;
}
});
My problem is creating the BackgroundMessage
type, as each action
will have a different value type.
I've tried this:
interface actions {
setUpdate: { total: number; alarm: boolean };
setReminder: { text: string; when: Date };
}
type BackgroundMessage = Record<keyof actions, actions>;
But I don't know how to specify that the keys of the action interface need to be in the action
property, and the value types in the value
property.
Is this possible?
Upvotes: 0
Views: 36
Reputation: 26307
You already have defined a map of actions to values, so you could use a mapped type to make a discriminated union from that map:
interface Actions {
setUpdate: { total: number; alarm: boolean };
setReminder: { text: string; when: Date };
}
type BackgroundMessage = {
[K in keyof Actions]: { action: K; value: Actions[K] };
}[keyof Actions];
Then you can narrow the type based on the action:
if (msg.action === "setReminder") {
msg.value.text // ok
}
Upvotes: 1