在Flow中,为什么会使用类而不是类型?
type Point = {x: number; y: number};
class Point = {x: number; y: number};
答案 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)
类提供标称类型,而对象类型提供结构类型。
假设我想要引入带有Vector
和x
字段的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 Types或Interfaces