你啥时候在流中使用接口而不是类型别名?

Posted

技术标签:

【中文标题】你啥时候在流中使用接口而不是类型别名?【英文标题】:When do you use an interface over a type alias in flow?你什么时候在流中使用接口而不是类型别名? 【发布时间】:2016-08-22 14:23:53 【问题描述】:

interfacetype 声明似乎做同样的事情。你什么时候使用一个而不是另一个?

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

以上是关于你啥时候在流中使用接口而不是类型别名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在流中定义具有指定类型的所有可选字段的泛型类型

防止在流中输入不需要的值

深入浅出TypeScript- 使用接口和类型别名

java的io流中,啥时候应该在流关闭之前加flush,啥时候不用

java的io流中,啥时候应该在流关闭之前加flush,啥时候不用

打字稿:为啥类型别名满足约束但相同的接口不满足?