3;
opaque type AliasAlias: ObjectAlias = ObjectAlias;
opaque type VeryOpaque: AliasAlias = ObjectAlias;
不透明别名类型 的类型检查
在文件内部
在文件内部跟正常的类型别名一样
//@flow
opaque type NumberAlias = number;
(0: NumberAlias);
function add(x: NumberAlias, y: NumberAlias): NumberAlias {
return x + y;
}
function toNumberAlias(x: number): NumberAlias { return x; }
function toNumber(x: NumberAlias): number { return x; }在文件外部
当你inport 一个 不透明的类型别是时候,他会隐藏基础类型
exports.js
export opaque type NumberAlias = number;imports.js
import type {NumberAlias} from './exports';
(0: NumberAlias) // Error: 0 is not a NumberAlias!
function convert(x: NumberAlias): number {
return x; // Error: x is not a number!
}子类型约束(subTyping Constraints)
当你添加一个子 类型约束在一个不透明的类型别名上时, 我们允许不透明类型在被定义文件的外部被用作父类型
exports.js
export opaque type ID: string = string;imports.js
import type {ID} from './exports';
function formatID(x: ID): string {
return "ID: " + x; // Ok! IDs are strings.
}
function toID(x: string): ID {
return x; // Error: strings are not IDs.
}当你创建一个拥有子类型约束的 不透明类型别名, 这个类型在类型中的位置一定要是这个类型的子类型在父类中的位置 (这里的概念应该是跟泛型的概念差不多, 不相关的类型不可以强制转换)
//@flow
opaque type Bad: string = number; // Error: number is not a subtype of string
opaque type Good: {x: string} = {x: string, y: number};泛型
不透明类型别名 有他们自己的泛型, 但是他们跟正常的泛型是差不多的
// @flow
opaque type MyObject<A, B, C>: { foo: A, bar: B } = {
foo: A,
bar: B,
baz: C,
};
var val: MyObject<number, boolean, string> = {
foo: 1,
bar: true,
baz: 'three',
};接口类型 (interface Types)
接口可以使一些拥有相同方法的类归为一类
// @flow
interface Serializable {
serialize(): string;
}
class Foo {
serialize() { return '[Foo]'; }
}
class Bar {
serialize() { return '[Bar]'; }
}
const foo: Serializable = new Foo(); // Works!
const bar: Serializable = new Bar(); // Works!如果你怕出错, 你可以手动的 使用 implements 告诉flow 哪些类实现了哪些接口,这可以预防你修改class 的时候出现错误
// @flow
interface Serializable {
serialize(): string;
}
class Foo implements Serializable {
serialize() { return '[Foo]'; } // Works!
}
class Bar implements Serializable {
// $ExpectError
serialize() { return 42; } // Error! // 不能返回一个number
}不要忘记了接口可以同时实现多个
接口的属性也是可以可选的
interface MyInterface {
property?: string;
}接口跟maps 联合
interface MyInterface {
[key: string]: number;
}接口泛型
interface MyInterface<A, B, C> {
property: A;
method(val: B): C;
}规矩还在,泛型你用了几个 ,你使用的时候 就要传递几个参数
// @flow
interface MyInterface<A, B, C> {
foo: A;
bar: B;
baz: C;
}
var val: MyInterface<number, boolean, string> = {
foo: 1,
bar: true,
baz: 'three',
};接口属性的 只读,与只写
接口属性默认是不可变
的, 但是你可以添加修饰符让他们变成 covariant
只读或者Contravariance
只写;(关于不可变想了解的请看这里)
interface MyInterface {
+covariant: number; // read-only 只读 不能修改
-contravariant: number; // write-only 只能修改, 不能读取
}混合只读
interface MyInterface {
+readOnly: number 关键词:javascript静态分类如何解析flow的用法(详细)