Flow中的class vs type

时间:2016-10-14 14:24:19

标签: flowtype

在Flow中,为什么会使用类而不是类型?

type Point = {x: number; y: number};
class Point = {x: number; y: number};

3 个答案:

答案 0 :(得分:6)

在您的示例中,您只需要一种类型。

但是如果你想定义方法,你会想要使用一个类。

class Point {
    x: number;
    y: number;
    constructor(x, y) {this.x = x; this.y = y;}
    distance_from_origin(): number { /* code goes here */ }
    angle_from_origin(): number { /* code goes here */ }
}

p: Point = new Point(2, 3);
d = p.distance_from_origin()

类型是编译时检查的流程功能,可帮助您捕获代码中的错误。在运行代码之前,它们完全从代码中删除。

类根本不是Flow特性(尽管Flow理解类 - 您创建的每个类也定义了Flow类型) - 它们是ES6的一个特性,即下一版本的JavaScript。 Babel,从您的代码中剥离Flow类型以使其成为有效JavaScript的程序,也可以将您的类转换为ES5兼容代码。

答案 1 :(得分:3)

类提供标称类型,而对象类型提供结构类型。

假设我想要引入带有Vectorx字段的y类型。当我去创建我的add(p: Point, v: Vector): Point函数时,结构类型证明是不合适的,例如

type Point = {x: number, y: number};
type Vector = {x: number, y: number};

function add(p: Point, v: Vector): Point {
  return {x: p.x + v.x, y: p.y + v.y};
}

const p1: Point = {x:0, y:5};
const p2: Point = {x:2, y:3};
const v: Vector = add(p1, p2); // This is not an error in Flow

对比具有类别的名义类型版本:

class Point { x: number; y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}
class Vector { x: number; y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}

function add(p: Point, v: Vector): Point {
  return new Point(p.x + v.x, p.y + v.y);
}

const p1: Point = new Point(0, 5);
const p2: Point = new Point(2, 3);
const v: Vector = add(p1, p2); // Error: p2 isn't a Vector

(实际上你可能会将add作为一个方法附加在点类上,但是我已经将它与对象类型示例的并行结构分开了。)

请注意,您可以使用标记字段从对象类型中获得一些标称类型的外观,例如

type Point = { tag: "point", x: number y: number };
type Vector = { tag: "vector", x: number, y: number };

如果你的班级没有任何方法,那么我建议你这样做。

答案 2 :(得分:1)

the documentation所示,flow以不同方式处理对象和类。 (即使你正在向ES5发展,也会在此之前进行流程检查。)

按名称比较课程。对象类型按结构进行比较。

实际上,类型别名 只是编写类型结构注释的一种较短方式。它就像一个包含较长表达式的变量。

type A = {wow: number}
type B = {wow: number}

let a:A = {wow: 1}
let b:B = {wow: 2}
; [a, b] = [b, a] // fine
console.log(a, b) // > { wow: 2 } { wow: 1 }

class C {
  constructor (x: number) { this.wow = x }
  wow: number
}
class D {
  constructor (x: number) { this.wow = x }
  wow: number
}
let c:C = new C(3)
let d:D = new D(4)

c = d // ERROR: D This type is incompatible with C
d = b // ERROR: object type This type is incompatible with D

如您所见,两个结构相同的类不兼容。

注意:有一些方法可以使不同的类兼容,例如Union TypesInterfaces