13.TypeScript中的类型别名

类型别名

类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。

type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
    
    
    if (typeof n === 'string') {
    
    
        return n;
    }
    else {
    
    
        return n();
    }
}

起别名不会新建一个类型 - 它创建了一个新 名字来引用那个类型。 给原始类型起别名通常没什么用,尽管可以做为文档的一种形式使用。

同接口一样,类型别名也可以是泛型 - 我们可以添加类型参数并且在别名声明的右侧传入:

type Container<T> = {
    
     value: T };

我们也可以使用类型别名来在属性里引用自己:

type Tree<T> = {
    
    
    value: T;
    left: Tree<T>;
    right: Tree<T>;
}

与交叉类型一起使用,我们可以创建出一些十分稀奇古怪的类型。

type LinkedList<T> = T & {
    
     next: LinkedList<T> };

interface Person {
    
    
    name: string;
}

var people: LinkedList<Person>;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;

接口 vs 类型别名

像我们提到的,类型别名可以像接口一样;然而,仍有一些细微差别。

其一,接口创建了一个新的名字,可以在其它任何地方使用。 类型别名并不创建新名字—比如,错误信息就不会使用别名。 在下面的示例代码里,在编译器中将鼠标悬停在 interfaced上,显示它返回的是 Interface,但悬停在 aliased上时,显示的却是对象字面量类型。

type Alias = {
    
     num: number }
interface Interface {
    
    
    num: number;
}
declare function aliased(arg: Alias): Alias;
declare function interfaced(arg: Interface): Interface;

另一个重要区别是类型别名不能被 extends和 implements(自己也不能 extends和 implements其它类型)。

枚举 vs 类型别名

一些场景中,使用类型别名比使用枚举更加方便。

使用枚举定义一个按钮组件尺寸的可选值:

enum Size {
    
    
    small,
    narmal,
    large
}

const size: Size = Size.small;

使用类型别名,可以更加方便和优雅:

type ButtonSize = 'small' | 'narmal' | 'large';

const size: ButtonSize = 'large';

使用类型别名可以表示一些内置类型不能表示的类型,进一步约束代码。

おすすめ

転載: blog.csdn.net/sinat_41212418/article/details/120895546