Here is the example given below in 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);
}
};
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.
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);
}
};
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
.
来源:https://stackoverflow.com/questions/50872258/flow-type-refinement-by-checking-for-existing-properties