为什么在这种情况下流会显示错误?

Why does flow show an error in this case?

我的代码:

/* @flow */

type Manager = {id: number, name: string};
type Target = {
  id: number,
  title: string,
};
type Form = {
  manager: ?Manager,
  target: ?Target,
}

const form: Form = {
  manager: {
    id: 1,
    name: 'test'
    },
  target: {
    id: 2,
    title: 'test'
  }
};

if (form.manager && form.target) {
  const managerId = +form.manager.id;
  const currentLimits = ([/* array from state*/].find(
    (limit) => limit.managersId === managerId,
  ) || {})
    .data || {};
  const { id: triggerId } = form.target; // <-- error here: "property `id` is missing in null or undefined [1]"
...
}

flow playground

因为您的 form.target 类型是 target: ?Target,这意味着“Targetnull/undefined”。

您需要事先检查 null 或删除 ?(但前提是您确定它不能为 null)。

示例:

if (form.manager && form.target) {
  const managerId = +form.manager.id;
  const currentLimits = ([/* array from state*/].find(
    (limit) => limit.managersId === managerId,
  ) || {})
    .data || {};

  if(form.target != null) { // <-- Check for null
    const { id: triggerId } = form.target;
  }
...
}

类型 Form 上的字段 target 是可选的,Flow 不够聪明,无法看到 if (form.manager && form.target) 检查防止 form.target 成为 nullundefined.

如果您将 form.target 访问包装在 if 子句中, 检查 form.target 是否为真,它将起作用。

let triggerId = null;
if (form.target) {
  ({ id: triggerId } = form.target);
}

See this example.

这里的问题是 array.find 中存在回调,它使之前由 if (form.manager && form.target) 语句完成的类型优化无效。

有关优化失效的更多信息here


对此的快速修复是在优化之前将 target 提取到它自己的变量中:

const { manager, target } = form;

if (manager && target) {
  const managerId = +manager.id;
  const currentLimits = ([/* array from state*/].find(
    (limit) => limit.managersId === managerId,
  ) || {}).data || {};
  const { id: triggerId } = target;
}

Try

或者只是在 find 回调之前移动解构:

if (form.manager && form.target) {
  const managerId = +form.manager.id;
  const { id: triggerId } = form.target;
  const currentLimits = ([/* array from state*/].find(
    (limit) => limit.managersId === managerId,
  ) || {})
    .data || {};
}

Try