流程代码可以是run here.
使用flow,我有一个函数,它接受一个键值对象并为它获取一个值 - 它得到的值应该是一个字符串,数字或布尔值。
type ValueType = string | number | bool | null | void;
type ObjectOfValues = {[string]: ValueType}
function getValueFromObjectOfValues(objectOfValues: ObjectOfValues, name: string): ValueType {
return objectOfValues[name];
}
我定义了一个具有maybe
字符串属性的对象类型:
type SomeValueWithNullableString = {
someProperty: ?string
}
然后我创建一个函数,它接受我的特定对象类型并调用函数从中获取值:
function getValue (someObject: SomeValueWithNullableString) {
return getValueFromObjectOfValues(someObject, 'someProperty');
}
这会导致流量错误:
输入ObjectOfValues = {[string]:ValueType} ^布尔。此类型与someProperty的预期参数类型不兼容: ?string ^ string 2:type ObjectOfValues = {[string]:ValueType} ^数字。此类型与9的预期参数类型不兼容:someProperty: ?string ^ string
我做错了什么?
答案 0 :(得分:1)
此代码的问题在于对象是可变的,因此getValueFromObjectOfValues
可以合法地执行objectOfValues.someProperty = 5
。
如果Flow允许此子类型关系,那么原始调用者(他们认为他们有一个someProperty
类型为?string
的对象)现在会有一个someProperty
类型为{number
的对象1}},从而打破了类型系统。
要解决此问题,您可以使用property variance。您需要更改类型:
type ObjectOfValues = {+[string]: ValueType}
这意味着,如果你有ObjectOfValues
类型的对象,那么你所知道的是它的属性是ValueType
的某个子类型。这意味着当您从中读取时,您将获得ValueType
。但Flow不会让你写信给他们,因为它不知道它们实际上是什么类型 - 只是它们是ValueType
的子类型。