简体   繁体   English

Flow为什么不理解可为空的属性与不可为空的对象属性兼容?

[英]Why doesn't Flow understand that nullable properties are compatible with non-nullable object properties?

I'm trying to understand why flow is complaining about incompatibility between the properties of two very similar objects ( try-flow-example ): 我试图理解为什么流程抱怨两个非常相似的对象( try-flow-example )的属性之间不兼容:

/* @flow */
type Cow = {
  name: ?string
}

type NamedCow = {
  name: string
}

function foo (c: Cow): string {
  if (c.name == null) return 'anonymous'
  return c.name
}

const elsa: NamedCow = { name: 'Elsa' }

foo(elsa)

Flow gives the following error with the above code: Flow使用上面的代码给出了以下错误:

17: foo(elsa)
        ^ NamedCow. This type is incompatible with the expected param type of
10: function foo (c: Cow): string {
                     ^ Cow
    Property `name` is incompatible:
        7:   name: string
                   ^ string. This type is incompatible with
        3:   name: ?string
                   ^ null or undefined

Why is the more specific name: string incompatible with the less specific name: ?string ? 为什么更具体的name: string与较不具体的name: ?string不兼容? Wouldn't NamedCow be covariant to Cow over the name property since the name property of NamedCow is a sub-set of the name property of Cow? NamedCow的name属性是Cow的name属性的子集吗, NamedCow在name属性上NamedCowCow协变?

Relevant docs: Flow docs on subtypes 相关文档: 子类型的流程文档

Object types are invariant. 对象类型是不变的。 This is due to the fact that object properties can be read and written. 这是因为可以读取和写入对象属性。

To see why covariance is unsafe, consider a function that assigns null to the property name in the foo function. 要了解为什么协方差不安全,请考虑一个在foo函数中为属性name分配null的函数。

Passing a Cow type: assignment to name = null poses no issue since name can be ?string . 传递Cow类型:分配给name = null不会造成任何问题,因为name可以是?string

But, if you pass a NamedCow type, the assignment to name = null would violate the type for name which is only string . 但是,如果您传递NamedCow类型,则对name = null的赋值将违反name的类型,后者仅为string


You can annotate name to be covariant by prefixing it with + , that is +name: ?string . 您可以通过在name加上+来将name注释为协变变量,即+name: ?string This indicates that no writes will be performed on it. 这表明不会对其执行任何写操作。 That should clear away the errors you're currently seeing. 那应该清除您当前看到的错误。 (The property variance modifiers are somewhat hidden in the docs ) (属性差异修饰符在文档有些隐藏

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 对不可为空的流类型细化不起作用 - Flow type refinement to non-nullable doesn't work 将 Flow/TypeScript JavaScript object 值类型转换为不可为空 - Cast Flow/TypeScript JavaScript object value types to non-nullable GraphQL 的不可为空错误没有提供太多细节,这可能让我进行调查 - Non-nullable error with GraphQL doesn't give much detail which might allow me to investigate GraphQL:不可为空的数组/列表 - GraphQL: Non-nullable array/list 为什么这会抛出“不能为不可为空的字段 Query.hello 返回 null。”? - Why does this throw "Cannot return null for non-nullable field Query.hello."? 为什么 graphql 返回“不能返回 null of non-nullable field mutation.createAccnt” - why is graphql returning “cannot return null of non-nullable field mutation.createAccnt” 为什么在执行更改时会收到“无法为不可为空的字段返回 null”错误? - Why am I getting a “Cannot return null for non-nullable field” error when doing a mutation? 无法在续集中插入具有不可为空外键的行 - Unable to insert row with non-nullable foreign key in sequelize 让TS抱怨与非空字段的空比较? - Getting TS to complain about null comparison to a non-nullable field? 无法为 GraphQL 查询中的不可空字段返回 null - Cannot return null for non-nullable field in a GraphQL query
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM