【问题标题】:How should union of Objects with optional properties be defined with Flow?Flow 应该如何定义具有可选属性的对象的联合?
【发布时间】:2017-06-17 16:44:20
【问题描述】:

我有一个处理两种类型参数的函数:字符串和对象。预期有 3 种不同的对象结构。这构成了多达 4 种可能的类型:

type URL = string;
type Item = {| href: string |};
type ItemList = {| results: Item[] |};
type Params = {| offset?: number, limit?: number |};

所以函数的选项类型是:

type Options = URL | Item | ItemList | Params;

这是实际的功能:

// No properties of "Params" are required
// so if they're all omitted, Params === {}
function request(opts: Options = {}) {
  if (typeof opts === 'string') {
    return 'opts is an URL';
  }

  if (typeof opts.href === 'string') {
    return 'opts is an item';
  }

  if (Array.isArray(opts.results)) {
    return 'opts is a list of items';
  }

  // Three of the four types are caught
  // we're left with "Params" which may or may not
  // have a "offset" and "limit" property.
  // Destructuring to undefined values is fine here.
  // Still, flow complains about the type not being met.
  const { offset, limit } = opts;
  return 'opts are parameters';
}

Flow 抱怨一些事情:

  1. opts = {} 引发不兼容错误。由于不需要Params 的属性,空对象不应该也匹配吗?请注意,opts = { offset: undefined } 会清除错误。
  2. 声明未找到属性“offset”和“limit”。由于它们都不是必需的,undefined 不应该是有效值吗?从而解构罚款?

总结一下我的问题:

你如何定义一个类型来接受不同类型的对象,其中一个没有必需的属性?

编辑:run the flow code in your browser

【问题讨论】:

    标签: javascript types flowtype


    【解决方案1】:

    查看Flowtype - making a sealed empty object 以获得您第一个问题的答案。

    对于第二个问题,答案基本上是 Flow 不完全支持这种类型的细化。 Disjoint unions 是为此用例设计的,尽管您必须为所有对象添加鉴别器属性。显然,这将需要对您的代码进行一些重要的更改。这是否可行由您决定。

    如果不可行,最好的办法可能是在这个函数中通过any 进行强制转换,并确保为返回值提供类型注释。它看起来足够小,人类很容易推理,所以在这里进行类型检查的好处可能不值得付出努力。当然,这是最好留给你的判断电话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-27
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 2023-01-12
      相关资源
      最近更新 更多