【问题标题】:Is it possible to detect missing Object.freeze() with Flow?是否可以使用 Flow 检测丢失的 Object.freeze()?
【发布时间】:2022-02-16 21:13:01
【问题描述】:

Flow 具有 $ReadOnly 实用程序类型 [1],它表示 T 的只读视图。不幸的是,由于 Flow 允许将可变 T 分配给其只读版本,它不能用于模拟 @987654322 的用法@。特别是,它无法检测到对后者的丢失呼叫。例如,给定

type Foo = { field: string };

// frozen is assumed to be immutable with no way to change it
type WithFrozenFoo = { +frozen: $ReadOnly<Foo> }

流类型检查以下代码:

let foo = { field: "test" };
foo.field = "new value";
let bar = { frozen: foo };
...
foo.field = "changed"; // Also changes bar.frozen.field

正确的代码应该是:

let foo = { field: "test" };
foo.field = "new value";
let bar = { frozen: Object.freeze(foo) };
...
foo = { ...foo, field: "changed" } 

理想情况下,Flow 应该提供一个单独的 $Frozen,它只能通过 Object.freeze() 从 T 分配实例。

但鉴于缺乏这一点,是否有可能以不同的方式对其进行建模,即使这会涉及到一个在内部使用任何功能的实用函数?

[1] - https://flow.org/en/docs/types/utilities/#toc-readonly

【问题讨论】:

    标签: flowtype


    【解决方案1】:

    事实证明,只需使用只读字段,我们就可以解决使冻结变得不必要的问题。缺点是在更新时克隆对象,但由于 Object.freeze() 可能比对象创建 [1] 慢,这是一个有用的折衷方案。

    type Foo = { +field: string };

    让 foo: Foo = { field: "test" }; foo = {...foo, field: "新值"};

    let bar = { freeze: foo }; ... // 现在流抱怨 foo.field = "改变";

    [1] - https://jsitor.com/jwRCuqLFN

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 2021-12-25
      • 2012-07-06
      相关资源
      最近更新 更多