在下面的代码示例中,目的是scrapeMovies
函数只接受可序列化的对象。
/* @flow */
type SerializableObjectType = {
[key: string]: string | number | boolean | $ReadOnlyArray<SerializableObjectType> | SerializableObjectType
};
type GuideType = {|
rid: string
|};
const guide: GuideType = {
rid: 'foo'
};
const scrapeMovies = async (guide: SerializableObjectType) => {};
scrapeMovies(guide);
我不理解flowtype抱怨scrapeMovies
被投放guide
对象的原因是什么,这对SerializableObjectType
的定义不那么严格。
这里定义子类型的正确方法是什么?
答案 0 :(得分:1)
传递GuideType
代替SerializableObjectType
是传递更具体类型的实例。默认情况下,Flow仅在函数中允许less specific(逆变/只写)输入。
要实现此目的,您需要将guide
参数标记为covariant。通过将对象标记为$ReadOnly<T>
,您将有效地将其标记为协变:
(Try)
type SerializableObjectType = {
[key: string]: string | number | boolean | $ReadOnlyArray<SerializableObjectType> | SerializableObjectType
};
type GuideType = {|
rid: string
|};
const guide: GuideType = {
rid: 'foo'
};
const scrapeMovies = async (guide: $ReadOnly<SerializableObjectType>) => {};
scrapeMovies(guide);
或者,您可以使用对象类型声明中的+
标记来标记specific properties as covariant/read-only:
(Try)
type SerializableObjectType = {
+[key: string]: string | number | boolean | $ReadOnlyArray<SerializableObjectType> | SerializableObjectType
};
type GuideType = {|
rid: string
|};
const guide: GuideType = {
rid: 'foo'
};
const scrapeMovies = async (guide: SerializableObjectType) => {};
scrapeMovies(guide);
你为什么要跳舞?为什么输入是协变/逆变/ whateverariant很重要?好吧,如果您尝试将guide
参数视为SerializeableObjectType
(一般对象图),并且您向number
密钥写了rid
,那么其他消费者guide
对象无法获得他们期望的结果。