代码之家  ›  专栏  ›  技术社区  ›  David Schumann Axnyff

通过检查现有属性进行流类型优化

  •  2
  • David Schumann Axnyff  · 技术社区  · 7 年前

    下面是 try flowtype

    export type TimeLineCourseType = {
        date: string,
        done: boolean,
        category_name: string,
    };
    
    export type TimeLineCatType = {
        date: string,
        done: boolean,
        rank_in_week: number,
    };
    
    export type TimeLineStatsType = {
        date: string,
        timespan: string
    };
    
    const displayTimelineItem = (item: TimeLineCourseType | TimeLineCatType | TimeLineStatsType, i: number) => {
        if (item.category_name) {
            return (
                item.playlist_name,
                item.category_name
            );
        } else if (item.rank_in_week) {
            return (
                item.rank_in_week
            );
        } else {
            return (item.timespan);
        }
    };
    

    从if-else块可以清楚地看到,每个块中的项只能是一种特定类型,而不是全部三种类型。但我有流量错误。还使用 hasOwnProperty 没有帮助。有办法解决这个问题吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Ross Allen    7 年前

    您可以创建此效果,称为 disjoint union 在flow中,为所有类型添加一个公共密钥并根据其值进行优化,或者切换到使用 exact types

    下面是一个使用 type 优化的关键:

    export type TimeLineCourseType = {
      date: string,
      done: boolean,
      category_name: string,
      type: 'TimeLineCourseType',
    };
    
    export type TimeLineCatType = {
      date: string,
      done: boolean,
      rank_in_week: number,
      type: 'TimeLineCatType',
    };
    
    export type TimeLineStatsType = {
      date: string,
      timespan: string
      type: 'TimeLineStatsType',
    };
    
    const displayTimelineItem = (item: TimeLineCourseType | TimeLineCatType | TimeLineStatsType, i: number) => {
      if (item.type === 'TimeLineCourseType') {
        return (
          item.playlist_name, 
          item.category_name
        );
      } else if (item.type === 'TimeLineCatType') {
        return (
          item.rank_in_week
        );
      } else {
        return (item.timespan);
      }
    };
    

    或者你可以继续你的方法 "exact" objects 用管子, {| |} 在花括号内:

    export type TimeLineCourseType = {|
      date: string,
      done: boolean,
      category_name: string,
    |};
    
    export type TimeLineCatType = {|
      date: string,
      done: boolean,
      rank_in_week: number,
    |};
    
    export type TimeLineStatsType = {|
      date: string,
      timespan: string
    |};
    
    const displayTimelineItem = (item: TimeLineCourseType | TimeLineCatType | TimeLineStatsType, i: number) => {
      if (item.category_name) {
        return (
          item.playlist_name, 
          item.category_name
        );
      } else if (item.rank_in_week) {
        return (
          item.rank_in_week
        );
      } else if (item.timespan) {
        return (item.timespan);
      }
    };
    

    管道之所以能起作用是因为 width subtyping 在流中,允许对象具有“额外”键。流在代码中不起作用,因为它对 TimeLineStatsType 拥有 rank_in_week 关键。流无法通过检查是否存在 兰克欣星期