Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/440.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 何时在流中的类型别名上使用接口?_Javascript_Flowtype - Fatal编程技术网

Javascript 何时在流中的类型别名上使用接口?

Javascript 何时在流中的类型别名上使用接口?,javascript,flowtype,Javascript,Flowtype,接口和类型声明似乎做了同样的事情。你什么时候用一个代替另一个 type Fooable = { foo(): string } vs 这是一个很好的问题。理想情况下,接口和对象类型之间没有区别。在实现时,它们之间存在一些(通常是细微的)差异 最大的区别是Flow将接口上声明的方法视为“只读”。这允许子类型为协变的w.r.t.方法,这是继承层次结构中非常常见的模式 随着时间的推移,我希望看到Flow统一这些概念,但在此之前,我的经验法则是在接口和对象类型之间进行选择: 使用对象类型来描述应

接口
类型
声明似乎做了同样的事情。你什么时候用一个代替另一个

type Fooable = {
  foo(): string
}
vs


这是一个很好的问题。理想情况下,接口和对象类型之间没有区别。在实现时,它们之间存在一些(通常是细微的)差异

最大的区别是Flow将接口上声明的方法视为“只读”。这允许子类型为协变的w.r.t.方法,这是继承层次结构中非常常见的模式

随着时间的推移,我希望看到Flow统一这些概念,但在此之前,我的经验法则是在接口和对象类型之间进行选择:

  • 使用对象类型来描述应用程序中传递的大量数据,例如React组件的props/state、Flux/Redux操作、类似JSON的东西
  • 使用接口来描述类似服务的接口。通常这些方法主要是Rx.Observable/Observer、Flux/Redux存储、抽象接口。如果类实例可能是您的类型的居住者,那么您可能需要一个接口

希望这有帮助

流中的接口可用于确保类实现某些方法和属性。例如:

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 }
参考资料:


  • 您能否对此进行扩展:
    这允许子类型是协变的w.r.t.方法
    type Foo = {
        property: string | number
    }
    
    // Good!
    let foo: Foo = { property: 42 }