什么时候在流中通过类型别名使用接口?
When do you use an interface over a type alias in flow?
interface
和 type
声明似乎做同样的事情。你什么时候使用一个而不是另一个?
type Fooable = {
foo(): string
}
对
interface Fooable {
foo(): string
}
这是一个很好的问题。理想情况下,接口和对象类型之间没有区别。在实施时,它们之间存在一些(通常是细微的)差异。
最大的区别是 Flow 认为在接口上声明的方法是 "read-only." 这允许子类型是协变的 w.r.t。方法,这是一种非常常见的继承层次结构模式。
我希望及时看到 Flow 统一这些概念,但在此之前,这是我在接口和对象类型之间进行选择的经验法则:
- 使用对象类型来描述在您的应用程序中传递的主要数据包,例如,props/state 用于 React 组件,Flux/Redux 操作,JSON 之类的东西。
- 使用接口来描述类似服务的接口。通常这些主要是方法,例如 Rx.Observable/Observer、Flux/Redux 存储、抽象接口。如果一个 class 实例很可能是你的类型的居民,你可能需要一个接口。
希望对您有所帮助!
Flow 中的接口可用于确保 class 实现某些方法和属性。例如:
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
class 将无法实现它:
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 }
参考文献:
interface
和 type
声明似乎做同样的事情。你什么时候使用一个而不是另一个?
type Fooable = {
foo(): string
}
对
interface Fooable {
foo(): string
}
这是一个很好的问题。理想情况下,接口和对象类型之间没有区别。在实施时,它们之间存在一些(通常是细微的)差异。
最大的区别是 Flow 认为在接口上声明的方法是 "read-only." 这允许子类型是协变的 w.r.t。方法,这是一种非常常见的继承层次结构模式。
我希望及时看到 Flow 统一这些概念,但在此之前,这是我在接口和对象类型之间进行选择的经验法则:
- 使用对象类型来描述在您的应用程序中传递的主要数据包,例如,props/state 用于 React 组件,Flux/Redux 操作,JSON 之类的东西。
- 使用接口来描述类似服务的接口。通常这些主要是方法,例如 Rx.Observable/Observer、Flux/Redux 存储、抽象接口。如果一个 class 实例很可能是你的类型的居民,你可能需要一个接口。
希望对您有所帮助!
Flow 中的接口可用于确保 class 实现某些方法和属性。例如:
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
class 将无法实现它:
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 }
参考文献: