【问题标题】:is there a easy way to use BroadcastChannel with typed Message instead o any?有没有一种简单的方法可以使用带有类型消息而不是任何消息的 BroadcastChannel?
【发布时间】:2022-06-13 00:23:15
【问题描述】:
const channel = new BroadcastChannel('foo');

channel.postMessage(<any>);

我知道有一个库(https://github.com/pubkey/broadcast-channel#create-a-typed-channel-in-typescript),但我不想包含任何额外的依赖项,我只想让 typescript 在编译时检查消息的类型

import { BroadcastChannel } from 'broadcast-channel';
declare type Message = {
  foo: string;
};
const channel: BroadcastChannel<Message> = new BroadcastChannel('foobar');
channel.postMessage({
  foo: 'bar'
});

【问题讨论】:

  • 您想实现相同的功能但不使用broadcast-channel 吗?喜欢this
  • 我想使用广播频道不让我发送或接收“任何”,而是一个具体的用户定义类型......也许这是不可能的......可能会以某种方式包装对象左右

标签: typescript broadcast channel


【解决方案1】:

您可以创建一个自定义类来扩展本机 BroadcastChannel,从而使 postMessage 方法严格输入:

export class StrictBroadcastChannel<
  MessageType extends Record<string, any>,
> extends BroadcastChannel {
  public postMessage(message: MessageType): void {
    return super.postMessage(message)
  }
}

用法:

type MessageType =
 | { type: 'hello', user: string }
 | { type: 'goodbye' }

const channel = new StrictBroadcastChannel<MessageType>()

channel.postMessage({ type: 'hello' }) // TypeError: missing "user"
channel.postMessage({ type: 'goodbye' }) // OK

您可以从这里开始任意复杂。我将消息结构嵌入到类本身中,因此所有消息都具有{ type: string, payload?: unknown } 形状,然后我创建了一个消息映射,如下所示:

interface DataMessageMap {
  DATA_START(clientId: string): void
  DATA_CHUNK(chunk: string): void
  DATA_END(): void
}

【讨论】:

    猜你喜欢
    • 2020-07-12
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多