深度子类型
假设我们有两个 类,它们使用 extends
具有子类型关系:
¥Assume we have two classes, which have a subtype relationship using extends
:
1class Person {2 name: string;3}4class Employee extends Person {5 department: string;6}
在需要 Person
实例的地方使用 Employee
实例是有效的。
¥It's valid to use an Employee
instance where a Person
instance is expected.
1class Person { name: string }2class Employee extends Person { department: string }3
4const employee: Employee = new Employee();5const person: Person = employee; // OK
但是,如果需要使用包含 Person
实例的对象,则使用包含 Employee
实例的对象是无效的。
¥However, it is not valid to use an object containing an Employee
instance
where an object containing a Person
instance is expected.
1class Person { name: string }2class Employee extends Person { department: string }3
4const employee: {who: Employee} = {who: new Employee()};5const person: {who: Person} = employee; // Error
这是一个错误,因为对象是可变的。employee
变量引用的值与 person
变量引用的值相同。
¥This is an error because objects are mutable. The value referenced by the
employee
variable is the same as the value referenced by the person
variable.
person.who = new Person();
如果我们写入 person
对象的 who
属性,我们还会更改 employee.who
的值,该值被显式注释为 Employee
实例。
¥If we write into the who
property of the person
object, we've also changed
the value of employee.who
, which is explicitly annotated to be an Employee
instance.
如果我们阻止任何代码通过 person
变量向对象写入新值,则使用 employee
变量将是安全的。Flow 为此提供了语法:
¥If we prevented any code from ever writing a new value to the object through
the person
variable, it would be safe to use the employee
variable. Flow
provides a syntax for this:
1class Person { name: string }2class Employee extends Person { department: string }3
4const employee: {who: Employee} = {who: new Employee()};5const person: {+who: Person} = employee; // OK6person.who = new Person(); // Error!
加号 +
表示 who
属性是 协变量。使用协变属性允许我们使用具有该属性的子类型兼容值的对象。默认情况下,对象属性是不变的,允许读取和写入,但它们接受的值受到更多限制。
¥The plus sign +
indicates that the who
property is covariant.
Using a covariant property allows us to use objects which have subtype-compatible
values for that property. By default, object properties are invariant, which allow
both reads and writes, but are more restrictive in the values they accept.
了解有关 属性差异 的更多信息。
¥Read more about property variance.