为什么具有已定义prop的对象类型不是具有Flow中可选prop的对象类型的子类型?

时间:2017-10-30 18:23:03

标签: javascript flowtype

在Flow中,我可以声明一个带有可选prop的对象类型,以便定义了该prop的对象满足它。

function getName(thing: {name?: string}): string {
  return thing.name || 'unknown';
}
getName({name: 'bob'}); // works

但是如果我在传递之前声明了param的对象类型,Flow会记录一个错误。

const thing: {name: string} = {name: 'bob'};
getName(thing); // error

那么为什么具有已定义道具的类型不满足具有与可选项相同的道具的类型?我该如何修复这些注释?

1 个答案:

答案 0 :(得分:5)

声明类型

function getName(thing: {name?: string}): string {
  return thing.name || 'unknown';
}

这意味着你的函数可以是类型安全的

function getName(thing: {name?: string}): string {
  thing.name = undefined;
  return "anything";
}

因为您说name被允许undefined

鉴于此,

const thing: {name: string} = {name: 'bob'};
getName(thing); // error

将破坏类型安全性,该值不再是字符串。

此处的解决方案是使用property variance。在您的用例中,这在您的用例中实际意味着您声明您的输入name属性`无法在函数内部更改。

function getName(thing: { +name?: string }): string {
  return thing.name || 'unknown';
}

因此Flow知道不允许修改name。如果它知道,那么传递{name: string}对象是安全的,这将允许您的代码工作。