Skip to main content

不透明类型别名

不透明类型别名是不允许在定义它们的文件之外访问其基础类型的类型别名。

¥Opaque type aliases are type aliases that do not allow access to their underlying type outside of the file in which they are defined.

1opaque type ID = string;

不透明类型别名与常规类型别名一样,可以在任何可以使用类型的地方使用。

¥Opaque type aliases, like regular type aliases, may be used anywhere a type can be used.

1opaque type ID = string;2
3function identity(x: ID): ID {4  return x;5}6export type {ID};

不透明类型别名语法

¥Opaque Type Alias Syntax

不透明类型别名是使用单词 opaque type 后跟其名称、等号 = 和类型定义创建的。

¥Opaque type aliases are created using the words opaque type followed by its name, an equals sign =, and a type definition.

opaque type Alias = Type;

你可以选择通过在名称后添加冒号 : 和类型来向不透明类型别名添加子类型约束。

¥You can optionally add a subtyping constraint to an opaque type alias by adding a colon : and a type after the name.

opaque type Alias: SuperType = Type;

任何类型都可以显示为超类型或不透明类型别名的类型。

¥Any type can appear as the super type or type of an opaque type alias.

1opaque type StringAlias = string;2opaque type ObjectAlias = {3  property: string,4  method(): number,5};6opaque type UnionAlias = 1 | 2 | 3;7opaque type AliasAlias: ObjectAlias = ObjectAlias;8opaque type VeryOpaque: AliasAlias = ObjectAlias;

不透明类型别名类型检查

¥Opaque Type Alias Type Checking

在定义文件中

¥Within the Defining File

当在同一文件中定义别名时,不透明类型别名的行为与常规 类型别名 完全相同。

¥When in the same file the alias is defined, opaque type aliases behave exactly as regular type aliases do.

1opaque type NumberAlias = number;2
30 as NumberAlias;4
5function add(x: NumberAlias, y: NumberAlias): NumberAlias {6    return x + y;7}8function toNumberAlias(x: number): NumberAlias { return x; }9function toNumber(x: NumberAlias): number { return x; }

定义文件之外

¥Outside the Defining File

当导入不透明类型别名时,它的行为类似于 标称类型,隐藏其基础类型。

¥When importing an opaque type alias, it behaves like a nominal type, hiding its underlying type.

exports.js

export opaque type NumberAlias = number;

imports.js

import type {NumberAlias} from './exports';

0 as NumberAlias; // Error: 0 is not a NumberAlias!

function convert(x: NumberAlias): number {
return x; // Error: x is not a number!
}

子类型化约束

¥Subtyping Constraints

当你向不透明类型别名添加子类型约束时,我们允许不透明类型在定义文件外部时用作超类型。

¥When you add a subtyping constraint to an opaque type alias, we allow the opaque type to be used as the super type when outside of the defining file.

exports.js

1export 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.
}

当你创建具有子类型约束的不透明类型别名时,类型位置中的类型必须是超类型位置中类型的子类型。

¥When you create an opaque type alias with a subtyping constraint, the type in the type position must be a subtype of the type in the super type position.

1opaque type Bad: string = number; // Error: number is not a subtype of string2opaque type Good: {x: string, ...} = {x: string, y: number};

泛型

¥Generics

不透明类型别名也可以有自己的 泛型,并且它们的工作方式与常规 类型别名 中的泛型完全相同

¥Opaque type aliases can also have their own generics, and they work exactly as generics do in regular type aliases

1opaque type MyObject<A, B, C>: {foo: A, bar: B, ...} = {2  foo: A,3  bar: B,4  baz: C,5};6
7var val: MyObject<number, boolean, string> = {8  foo: 1,9  bar: true,10  baz: 'three',11};

库定义

¥Library Definitions

你还可以在 库定义文件 中声明不透明类型别名。在那里,你可以省略基础类型,但仍然可以选择包含超类型。

¥You can also declare opaque type aliases in libdefs. There, you omit the underlying type, but may still optionally include a super type.

1declare opaque type Foo;2declare opaque type PositiveNumber: number;