首页 文章

流 - 可能类型与联合类型不兼容

提问于
浏览
0

流程代码可以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');
}

这会导致流量错误:

type ObjectOfValues = {[string]:ValueType} ^ boolean . 此类型与someProperty的预期param类型不兼容:?string ^ string 2:type ObjectOfValues = {[string]:ValueType} ^ number . 此类型与9的预期参数类型不兼容:someProperty:?string ^ string

我究竟做错了什么?

1 回答

  • 1

    这段代码的问题在于对象是可变的,所以 getValueFromObjectOfValues 可以合法地做 objectOfValues.someProperty = 5 .

    如果Flow允许这种子类型关系,那么原始调用者认为他们有一个 someProperty 类型为 ?string 的对象,现在会有一个 someProperty 类型为 number 的对象,从而破坏了类型系统 .

    要解决此问题,您可以使用property variance . 你需要像这样改变你的类型:

    type ObjectOfValues = {+[string]: ValueType}

    这意味着松散地,如果你有一个 ObjectOfValues 类型的对象,你所知道的是它的属性是 ValueType 的某个子类型 . 这意味着当你从他们那里读取时,你会得到 ValueType . 但Flow知道他们实际上是什么类型 - 只是他们是 ValueType 的子类型 .

相关问题