用流类型缩小多个属性的问题

时间:2019-12-10 21:40:47

标签: flowtype

我想知道为什么下面的代码在流程中无效。

Flowtyped try link

/* @flow */

type Foo = {
  bar: string
}

type Data = {
  acme: null | { nodes: Foo[] },
  beta: null | { nodes: Foo[] }
}

function a(data: Data|null) {
  if (
    !data ||
    !data.acme ||
    !data.acme.nodes ||
    !data.beta ||
    !data.beta.nodes
  ) {
    return
  }

  const filteredAcme: Foo[] = data.acme.nodes.filter(Boolean);
  const filteredBeta: Foo[] = data.beta.nodes.filter(Boolean); // <-- error on this line
  // Cannot get `data.beta.nodes` because property `nodes` is missing in null [1].
}

似乎if语句应该缩小类型,以便我们知道存在beta.nodes。

1 个答案:

答案 0 :(得分:0)

应该,但是当前版本的流无法很好地检测对象属性上检查的内容,因此创建局部变量应该会有所帮助。如下所示:

Check in Flow Try

/* @flow */

type Foo = {
  bar: string
}

type Data = {
  acme: null | { nodes: Foo[] },
  beta: null | { nodes: Foo[] }
}

function a(data: Data|null) {
  if (!data) return

  const {beta, acme} = data;
  if (!beta || !beta.nodes || !acme || !acme.nodes) return ;

  const filteredAcme: Foo[] = acme.nodes.filter(Boolean);
  const filteredBeta: Foo[] = beta.nodes.filter(Boolean); // <-- ???
}

function b(data: Data|null) {
  if (!data) return
  if (!data.acme) return
  if (!data.acme.nodes) return

  const filteredAcme: Foo[] = data.acme.nodes.filter(Boolean);

  if (!data.beta) return 
  if (!data.beta.nodes) return

  const filteredBeta: Foo[] = data.beta.nodes.filter(Boolean);
}

function c(data: Data|null) {
  if (!data) return
  if (!data.acme) return
  if (!data.acme.nodes) return
  const {beta} = data;
  if (!beta) return 
  if (!beta.nodes) return

  const filteredAcme: Foo[] = data.acme.nodes.filter(Boolean);  
  const filteredBeta: Foo[] = beta.nodes.filter(Boolean);
}