Javascript 如何使用流定义具有可选属性的对象的并集?

Javascript 如何使用流定义具有可选属性的对象的并集?,javascript,types,flowtype,Javascript,Types,Flowtype,我有一个处理两种类型参数的函数:字符串和对象。预期有3种不同的对象结构。它最多可构成4种可能的类型: type URL = string; type Item = {| href: string |}; type ItemList = {| results: Item[] |}; type Params = {| offset?: number, limit?: number |}; 因此,函数的选项类型为: type Options = URL | Item | ItemList | Par

我有一个处理两种类型参数的函数:字符串和对象。预期有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在抱怨一些事情:

opts={}引发不兼容错误。既然不需要参数的属性,空对象不也应该匹配它吗?请注意,opts={offset:undefined}会清除错误。 未找到声明的属性偏移量和限制。既然它们都不是必需的,那么未定义的值不应该是有效值吗?这样的解构很好吗? 总结一下我的问题:

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

编辑:。

查看第一个问题的答案

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

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