不透明類型別名(Opaque Type Aliases)
通過(guò)類型系統(tǒng)加強(qiáng)抽象
不透明類型別名是類型別名煌集,它們不允許在定義它們的文件之外訪問其基礎(chǔ)類型。
opaque type ID = string;
function identity(x: ID): ID {
return x;
}
export type {ID};
不透明類型語(yǔ)法(Opaque Type Alias Syntax)
opaque type Alias = Type;
你可以通過(guò)在名稱后面添加: type
來(lái)選擇性地將子類型約束添加到不透明類型別名中敏簿。
opaque type Alias: SuperType = Type;
任何類型都可以成為超類型或不透明類型的別名。
opaque type StringAlias = string;
opaque type ObjectAlias = {
property: string,
method(): number,
};
opaque type UnionAlias = 1 | 2 | 3;
opaque type AliasAlias: ObjectAlias = ObjectAlias;
opaque type VeryOpaque: AliasAlias = ObjectAlias;
不透明類型別名類型檢查
在定義文件中
在同一文件中定義別名時(shí)百框,不透明類型別名的行為與常規(guī)類型別名完全相同露懒。
//@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; }
在定義文件之外
當(dāng)導(dǎo)入一個(gè)不透明類型的別名時(shí),它的行為就像一個(gè)名義類型读宙,隱藏了它的基礎(chǔ)類型彻秆。
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.
}
當(dāng)你使用子類型約束創(chuàng)建不透明類型別名時(shí),類型位置中的類型必須是超類型位置中的類型的子類型结闸。
//@flow
opaque type Bad: string = number; // Error: number is not a subtype of string
opaque type Good: {x: string} = {x: string, y: number};
泛型(Generics)
不透明類型別名也可以有自己的泛型唇兑,而且它們的工作方式與普通類型別名一樣。
// @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',
};