TypeScript教程之八:联合类型,交叉类型及枚举类型


由微软推出的TypeScript自从一推出就广受关注,现在无论开发前端React/Vue,还是后端API,很多项目中都广泛接受了TypeScript。下面介绍TS中的联合类型,交叉类型及枚举类型。

TypeScript

Union type联合类型

在联合类型中使用基本类型

所谓联合类型,就是两种或多种变量类型的组合。比如:对于一个函数的参数,可以接受字符串或者数字型的参数。但在函数中,需要根据类型的不同实现不同的逻辑。这里可以使用typeof来识别:

function addFunction(a: string|Number, b: string|number) {
    if (typeof a === "number" && typeof b === "number")
        return a + b;

    return `${a}${b}`;
}

console.log(addFunction(3, 5));
console.log(addFunction("Hello, ", "TS"));
console.log(addFunction("Hello,", 123));

在联合类型中使用类

在传递对象给函数后,就要使用instanceof来识别接受变量的类型了:

class Cat {
    meow() {
        console.log("Meow...");
    }
}

class Dog {
    bark() {
        console.log("Woaf...");
    }
}

function animalSpeak(animal: Cat|Dog) {
    if (animal instanceof Cat)
        (animal as Cat).meow();
    else if (animal instanceof Dog)
        (animal as Dog).bark();
}

const c = new Cat();
const d = new Dog();

animalSpeak(c);
animalSpeak(d);

再举一个例子:

type ServerState =
  | HTTP_200
  | HTTP_401
  | HTTP_403
  | HTTP_500;
 
function logger(s: ServerState) {
  switch (s.state) {
    case 200:
      return "OK";
    case 401:
      return `Error ${s.message}`;
    case 500:
      return "Server error";
  }
}

Intersection type交叉类型

TS中的交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。在这里,单一类型就可能被重用。

例如:

interface Identity {
    id: number;
    name: string;
}

interface Contact {
    email: string;
    phone: string;
    address: string;
}

type Staff = Identity & Contact;
// type customer = Identity & XXX & YYY

enum枚举类型

通过枚举类型,可以列举出所有可能的合法值。比如:

enum JOB_TITLE {
    DIRECTOR,
    MANAGER,
    ARCHITECT,
    DEVELOPER,
}

Template Literals及Exclude的使用

有些时候,要对某个属性值进行限定,比如当描述屏幕上位置的时候,可以使用:

  • left-top
  • left-center
  • left-bottom
  • center-top
  • center
  • center-bottom
  • right-top
  • right-center
  • right-bottom

这个时候可以使用联合类型,但更为简洁的方式是使用模板字面值(Template Literals)。比如:

type HorizontalPosition = 'left' | 'center' | 'right';
type VerticalPosition = 'top' | 'center' | 'bottom';

type MixedProps1 = {
    position: `${HorizontalPosition}-${VerticalPosition}`
}

const test1: MixedProps1 = {position: 'left-center'};
console.log(test1);

经过如上定义后,如果进行如下赋值,就会报错:

const test1: MixedProps1 = {position: 'leftcenter'};

其错误提示为:

Type '"leftcenter"' is not assignable to type '"left-center" | "left-top" | "left-bottom" | "center-center" | "center-top" | "center-bottom" | "right-center" | "right-top" | "right-bottom"'. Did you mean '"left-center"'?(2820)

但也可以看到一个问题,’center-center’看起来有些奇怪,可以改进为如下:

type HorizontalPosition = 'left' | 'center' | 'right';
type VerticalPosition = 'top' | 'center' | 'bottom';

type MixedProps1 = {
    position: Exclude<`${HorizontalPosition}-${VerticalPosition}`, 'center-center'>
    | 'center'
}

const test1: MixedProps1 = {position: 'center'};

文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !
  目录