使用 iframe 时输入检查 instanceof 的安全方法?

Type safe way to check instanceof while working with iframes?

我有一个由 Flow 检查的代码基类型,我经常使用 instanceof 来进行类型优化。

我现在需要让我的代码在元素来自 iframe 时工作,而 instanceof 在这种情况下不起作用,because each window has its own instances

我试图定义一个 getOwnElement 帮助器以从 defaultView 获取 Element,但是如果我随后使用检索到的 Elementinstanceof 检查失败对于流量:

declare function getOwnElement(node: Element): Element;
function getOwnElement(node) {
  return node.ownerDocument.defaultView.Element;
}

const ownElement = getOwnElement(element);
element instanceof ownElement && element; // element is marked as `empty`

所以现在我想知道我应该如何更新我的代码以保持它的类型安全并使用 iframe?

我有两个建议。两者都不是完全类型安全的,但安全性的缺乏包含在易于测试和手动验证的小函数中。对于这两者,如果您使用 node.ownerDocument.defaultView.Element 属性 传递一个不相关的对象,您将有可能得到不正确的结果,但这似乎是一个非常小的风险。我没有在运行时测试这些,但任何需要的调整都应该相对较小。

declare class Element {};

function asElement(node: any): ?Element {
  const OwnElement = node?.ownerDocument?.defaultView?.Element;
  if (OwnElement != null && node instanceof OwnElement) {
    return node;
  } else {
    return null;
  }
}

function doThingWithElement(whatever: mixed): void {
  const element = asElement(whatever);
  if (element != null) {
    (element: Element);
    // Expected error
    (element: string);
  }
}

(try)

在这个例子中,asElement 是一个函数,它在考虑 iframe 问题的情况下进行 instanceof 检查,而 returns 参数当且仅当它通过检查时。然后,您可以使用普通的无效性检查进行优化。

declare class Element {};

declare function isElement(node: any): boolean %checks (node instanceof Element);
function isElement(node) {
  const OwnElement = node?.ownerDocument?.defaultView?.Element;
  return OwnElement != null && node instanceof OwnElement;
}

function doThingWithElement(whatever: mixed): void {
  if (isElement(whatever)) {
    (whatever: Element);
    // Expected error
    (whatever: string);
  }
}

(try)

这将创建一个 isElement 函数,您可以直接使用它来执行优化。

顺便说一句,ElementElement class 实例的类型,而不是 class 本身。 Class<Element> 是 class 本身的类型,但似乎 Flow 不执行类型优化,其中右侧具有动态创建的 class.