class vs 输入 Flow
class vs type in Flow
在 Flow 中,为什么要使用 class 而不是类型?
type Point = {x: number; y: number};
class Point = {x: number; y: number};
在您的示例中,您只需要一个类型。
但是如果你想定义方法,你会想要使用 class。
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 理解 classes - 你创建的每个 class 也定义了一个 Flow 类型) - 它们是ES6,下一个版本JavaScript。 Babel 是从您的代码中剥离 Flow 类型以使其有效的程序 JavaScript,它还可以将您的 classes 转换为 ES5 兼容代码。
如 the documentation 中所示,流以不同方式处理对象和 classes。 (即使你正在迁移到 ES5,流检查也会在此之前发生。)
A class 按名称比较。对象类型按结构比较。
事实上,type alias只是类型结构注解的一种较短的写法。它就像一个包含较长表达式的变量。
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
如您所见,两个具有相同结构的class不兼容。
注意:有多种方法可以使不同的 classes 兼容,例如 Union Types or Interfaces
类 提供名义类型,而对象类型提供结构类型。
假设我想引入一个带有 x
和 y
字段的 Vector
类型。当我去创建我的 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
将其与 classes 的名义类型版本进行对比:
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
作为点 class 上的方法附加,但我已将其与对象类型示例的并行结构分开。)
请注意,您可以使用标记字段从对象类型中获取一些名义类型的表象,例如
type Point = { tag: "point", x: number y: number };
type Vector = { tag: "vector", x: number, y: number };
如果您的 class 没有任何方法,那么我建议您这样做。
在 Flow 中,为什么要使用 class 而不是类型?
type Point = {x: number; y: number};
class Point = {x: number; y: number};
在您的示例中,您只需要一个类型。
但是如果你想定义方法,你会想要使用 class。
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 理解 classes - 你创建的每个 class 也定义了一个 Flow 类型) - 它们是ES6,下一个版本JavaScript。 Babel 是从您的代码中剥离 Flow 类型以使其有效的程序 JavaScript,它还可以将您的 classes 转换为 ES5 兼容代码。
如 the documentation 中所示,流以不同方式处理对象和 classes。 (即使你正在迁移到 ES5,流检查也会在此之前发生。)
A class 按名称比较。对象类型按结构比较。
事实上,type alias只是类型结构注解的一种较短的写法。它就像一个包含较长表达式的变量。
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
如您所见,两个具有相同结构的class不兼容。
注意:有多种方法可以使不同的 classes 兼容,例如 Union Types or Interfaces
类 提供名义类型,而对象类型提供结构类型。
假设我想引入一个带有 x
和 y
字段的 Vector
类型。当我去创建我的 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
将其与 classes 的名义类型版本进行对比:
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
作为点 class 上的方法附加,但我已将其与对象类型示例的并行结构分开。)
请注意,您可以使用标记字段从对象类型中获取一些名义类型的表象,例如
type Point = { tag: "point", x: number y: number };
type Vector = { tag: "vector", x: number, y: number };
如果您的 class 没有任何方法,那么我建议您这样做。