你啥时候在流中使用接口而不是类型别名?
Posted
技术标签:
【中文标题】你啥时候在流中使用接口而不是类型别名?【英文标题】:When do you use an interface over a type alias in flow?你什么时候在流中使用接口而不是类型别名? 【发布时间】:2016-08-22 14:23:53 【问题描述】:interface
和 type
声明似乎做同样的事情。你什么时候使用一个而不是另一个?
type Fooable =
foo(): string
对
interface Fooable
foo(): string
【问题讨论】:
【参考方案1】:Flow 中的接口可用于确保类实现某些方法和属性。例如:
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"
此外,类型和接口之间还有更细微的区别。
默认情况下,接口属性是不变的。例如:
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!
另一方面,对于类型,Flow 不会抱怨:
type Foo =
property: string | number
// Good!
let foo: Foo = property: 42
参考资料:
-
Flow interfaces
Type variance
【讨论】:
【参考方案2】:这是一个很好的问题。理想情况下,接口和对象类型之间没有区别。在实施时,它们之间存在一些(通常是细微的)差异。
最大的不同是 Flow 认为在接口上声明的方法是“只读的”。这允许子类型是协变的 w.r.t。方法,这是继承层次结构中非常常见的模式。
我希望看到 Flow 将这些概念统一起来,但在此之前,这是我在接口和对象类型之间进行选择的经验法则:
使用对象类型来描述在您的应用中传递的主要数据包,例如 React 组件的 props/state、Flux/Redux 操作、类似 JSON 的内容。 使用接口来描述类似服务的接口。通常这些主要是方法,例如,Rx.Observable/Observer、Flux/Redux 存储、抽象接口。如果一个类实例可能是您的类型的居民,您可能需要一个接口。希望这会有所帮助!
【讨论】:
你能详细说明一下吗:This allows subtypes to be covariant w.r.t. methods
?以上是关于你啥时候在流中使用接口而不是类型别名?的主要内容,如果未能解决你的问题,请参考以下文章
java的io流中,啥时候应该在流关闭之前加flush,啥时候不用