qazxsw poi和qazxsw poi声明似乎做同样的事情。你什么时候用另一个?
interface
VS
type
这是一个很好的问题。理想情况下,接口和对象类型之间没有区别。实施后,它们之间存在一些(通常是微妙的)差异。
最大的区别是Flow认为在接口上声明的方法是“只读”。这允许子类型与w.r.t协变。方法,这是一种具有继承层次结构的非常常见的模式。
随着时间的推移,我希望看到Flow统一这些概念,但在此之前,这是我在接口和对象类型之间进行选择的经验法则:
希望这可以帮助!
Flow中的接口可用于确保类实现某些方法和属性。例如:
type Fooable = {
foo(): string
}
但是,如果我们定义一个等效的interface Fooable {
foo(): string
}
类型,我们的interface IFly {
fly(): string
}
// Good!
class Duck implements IFly {
fly() {
return "I believe I can fly"
}
}
// Bad! Cannot implement `IFly` with `Duck` because number is incompatible with string in the return value of property `fly`.
class Duck implements IFly {
fly() {
return 42
}
}
// Bad! Cannot implement `IFly` with `Duck` because property `fly` is missing in `Duck` but exists in `IFly`.
class Duck implements IFly {
quack() {
return "quack quack"
}
}
类将无法实现它:
IFly
此外,类型和接口之间存在更微妙的差异。
默认情况下,接口属性是不变的。例如:
Duck
要使接口属性协变,需要将它们设置为只读:
type IFly = {
fly(): string
}
// Cannot implement `Fly` because it is not an interface.
class Duck implements Fly {
fly() {
return "I believe I can fly"
}
}
另一方面,对于类型,Flow不会抱怨:
interface Foo {
property: string | number
}
let foo: Foo = { property: 42 } // Cannot assign object literal to `foo` because number is incompatible with string in property `property`.
参考文献:
interface Foo {
+property: string | number
}
let foo: Foo = { property: 42 } // Good!
type Foo = {
property: string | number
}
// Good!
let foo: Foo = { property: 42 }