混合传递中缺少 Flow 属性

len*_*myr 10 javascript flowtype

我正在使用 aBroadcastChannel将数据从一个浏览器窗口传递到另一个浏览器窗口。但是,使用 Flow 时出现以下错误:Flow:mixed [1] 中缺少属性 `type`。

这是我的代码:

const channel = new BroadcastChannel('background');
channel.onmessage = ({ data }) => {
  if (data.type === 'OK') {
    this.setState({ isLoading: false, success: true, error: false });
  }
  else if (data.type === 'ERROR') {
    this.setState({ isLoading: false, success: false, error: true });
  }
};
Run Code Online (Sandbox Code Playgroud)

我也尝试定义我自己的类型:

type MessageType = {
  type: String,
  payload: String,
};

...

channel.onmessage = ({ data }: { data: MessageType }) => {
  if (data.type === 'OK') {
    this.setState({ isLoading: false });
  }

  if (data.type === 'ERROR') {
    alert('ERROR!');

    this.setState({ isLoading: false });
  }
};
Run Code Online (Sandbox Code Playgroud)

但是 Flow 给了我以下错误:Flow:无法将函数分配给 `channel.onmessage`,因为 `MessageType` [1] 与第一个参数的属性 `data` 中的混合 [2] 不兼容。

我发现消息处理程序传递的参数声明如下:

declare class MessageEvent extends Event {
  data: mixed;
  origin: string;
  lastEventId: string;
  source: WindowProxy;
}
Run Code Online (Sandbox Code Playgroud)

所以,如果数据被声明为混合类型,但我需要它是自定义类型,我该怎么做?

Pet*_*all 6

type 的值mixed绝对可以是任何东西,包括undefinednull或者没有prototype.

在能够访问它之前,您需要明确检查实际类型是否data有一个type字段:

channel.onmessage = ({ data }) => {
  // 1. Make sure it's not null
  // 2. Make sure it's an object. This is only so that we can...
  // 3. ...call hasOwnProperty to make sure it has a 'type' field
  if(data != null && typeof data === 'object' && data.hasOwnProperty('type')) {
    // Inside this condition, Flow knows that the 'type' field exists
    if (data.type === 'OK') {
      this.setState({ isLoading: false, success: true, error: false });
    }
    else if (data.type === 'ERROR') {
      this.setState({ isLoading: false, success: false, error: true });
    }
  }
};
Run Code Online (Sandbox Code Playgroud)