Skip to main content

宽度子类型

如果该对象类型是 不精确的,则在用一组特定属性注释的位置使用具有 "额外的" 属性的对象是安全的。

¥It's safe to use an object with "extra" properties in a position that is annotated with a specific set of properties, if that object type is inexact.

1function func(obj: {foo: string, ...}) {2  // ...3}4
5func({6  foo: "test", // Works!7  bar: 42      // Works!8});

func 中,我们知道 obj 至少有一个属性 foo,并且属性访问表达式 obj.foo 将具有类型 string

¥Within func, we know that obj has at least a property foo and the property access expression obj.foo will have type string.

这是一种通常称为 "宽度子类型" 的子类型,因为 "更宽的" 类型(即具有更多属性)是较窄类型的子类型。

¥This is a kind of subtyping commonly referred to as "width subtyping" because a type that is "wider" (i.e., has more properties) is a subtype of a narrower type.

因此,在下面的示例中,obj2obj1 的子类型。

¥So in the following example, obj2 is a subtype of obj1.

1let obj1: {foo: string, ...}  = {foo: 'test'};2let obj2 = {foo: 'test', bar: 42};3obj2 as {foo: string, ...};

然而,知道某个属性肯定不存在通常很有用。

¥However, it's often useful to know that a property is definitely absent.

1function func(obj: {foo: string, ...} | {bar: number, ...}) {2  if (obj.foo) {3    obj.foo as string; // Error!4  }5}

上面的代码存在类型错误,因为 Flow 还允许调用表达式 func({foo: 1, bar: 2}),因为 {foo: number, bar: number}{bar: number, ...} 的子类型,{bar: number, ...} 是参数联合类型的成员之一。

¥The above code has a type error because Flow would also allow the call expression func({foo: 1, bar: 2}), because {foo: number, bar: number} is a subtype of {bar: number, ...}, one of the members of the parameter's union type.

对于像这样断言不存在属性很有用的情况,你可以使用 确切的对象类型

¥For cases like this where it's useful to assert the absence of a property, You can use exact object types.

1function func(obj: {foo: string} | {bar: number}) {2  if (obj.foo) {3    obj.foo as string; // Works!4  }5}

确切的对象类型 禁用宽度子类型,并且不允许存在其他属性。

¥Exact object types disable width subtyping, and do not allow additional properties to exist.

使用精确的对象类型可以让 Flow 知道运行时不会存在额外的属性,这使得 改进 变得更加具体。

¥Using exact object types lets Flow know that no extra properties will exist at runtime, which allows refinements to get more specific.