通过检查现有属性细化流类型 [英] Flow Type refinement by checking for existing properties

查看:99
本文介绍了通过检查现有属性细化流类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是在尝试流动型

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也无济于事.有什么办法解决吗?

It is clear from the if else blocks, that the item in each can only be of one specific type, not all three. Yet I get flow errors. Also using hasOwnProperty does not help. Is there any way around this?

推荐答案

您可以创建这种效果,称为

You can create this effect, called a disjoint union in Flow, by either adding a common key to all types and refining based on its value or switching to using exact types.

下面是使用type键进行细化的示例:

here's an example using a type key to refine:

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);
  }
};

或者您可以通过将类型设置为精确"对象,带有管道,{| |}在花括号内:

or you can continue with your approach by making the types "exact" objects with pipes, {| |} inside the curly brackets:

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);
  }
};

管道之所以能够成功,是因为在Flow中宽度子类型 ,对象可以使用额外"键. Flow在您的代码中不起作用,因为例如,TimeLineStatsType具有rank_in_week键是有效的. Flow无法通过检查rank_in_week的存在来优化类型.

The pipes make this work because due to width subtyping in Flow, objects are allowed to have "extra" keys. Flow doesn't work in your code because, for example, it's valid for a TimeLineStatsType to have a rank_in_week key. Flow can't refine the type by checking for the existence of rank_in_week.

这篇关于通过检查现有属性细化流类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆