为什么flowtype认为我的变量未定义?

时间:2018-04-26 13:59:22

标签: javascript flowtype

我有一个如下所示的flowtype对象声明:

   type ProjectType = {
     // removed for brevity
     releases?: Array<ReleaseType>
   }

有时候对象中不包含版本,所以当我想使用它时,我首先要对它进行条件检查。所以在这里,稍后在我的代码中,我在这样的条件之后访问该数组:

   if (selectedProject
      && selectedProject.releases
      && selectedProject.releases.length) {
      majorReleasesSet = new Set(selectedProject.releases.map((release: ReleaseType): string => (
        release.major)));
      projectHasNoReleases = false;
      projectLatestMajorRelease = selectedProject.releases.slice(-1)[0].major;
      projectLatestMinorRelease = selectedProject.releases.slice(-1)[0].minor;
    }

但是流量并不喜欢这样,抱怨道:

Cannot call selectedProject.releases.slice because property slice is missing in undefined [1].

     components/TimeEntries/EntryForm.jsx
     123│         release.major)));
     124│       projectHasNoReleases = false;
     125│       projectLatestMajorRelease = selectedProject.releases.slice(-1)[0].major;
     126│       projectLatestMinorRelease = selectedProject.releases.slice(-1)[0].minor;
     127│     }
     128│
     129│     const projectLatestRelease = `${projectLatestMajorRelease}.${projectLatestMinorRelease}`;

我错过了什么?我尝试添加Array.isArray(selectedProject.releases),但流程仍然抱怨。 Flow列出了第125和126行的错误。

1 个答案:

答案 0 :(得分:1)

我会说,你做一些有潜在影响的事情(运行map函数,创建一个集合等)这一事实使Flow担心releases属性可能在对象上发生了变化。在您运行函数后,Flow将基本丢弃您的任何改进。

Here's an example of your code, as-is, throwing an error

解决此问题的最简单方法是将对象的releases拉入单独的值并对其执行空检查。这样,Flow肯定它仍然不是null:

Try

// Mock this
type ReleaseType = {
  major: string;
  minor: string,
}

type ProjectType = {
  // removed for brevity
  releases?: Array<ReleaseType>
}

var selectedProject: ProjectType = {
  major: "foo",
  minor: "bar",
}

// Set up some variables for this example since I
// don't have any context on them
declare var majorReleasesSet: Set<any>;
declare var projectHasNoReleases: any;
declare var projectLatestMajorRelease: any;
declare var projectLatestMinorRelease: any;

// The `const {releases} = whateverObject` is the important part here
const {releases} = selectedProject || {};
if (releases && releases.length) {
  majorReleasesSet = new Set(releases.map((release: ReleaseType): string => (release.major)));
  projectHasNoReleases = false;
  projectLatestMajorRelease = releases.slice(-1)[0].major;
  projectLatestMinorRelease = releases.slice(-1)[0].minor;
}