您的位置:

typescript联合类型详解

一、typescript联合类型判断

在typescript中,我们可以使用联合类型来表示值可以是几种类型中的一种。举个例子,我们可以这样定义一个变量:

let strOrNum: string | number;

这里的 | 符号就表示联合类型,变量 strOrNum 可以是字符串或者数字类型。

在运行时,我们很容易就可以判断这个变量的类型:

if (typeof strOrNum === "string") {
    console.log("这是一个字符串!");
} else {
    console.log("这是一个数字!");
}

这里使用 typeof 来获取变量的类型,在判断的时候,我们就可以根据不同的类型输出不同的结果。

这里需要注意一点的是,联合类型并不是类型之间的交集,而是其中的一种类型。例如:

let strOrNum: string | number;
strOrNum = "hello";
strOrNum = 42; // 这里不会出错,因为 number 也是 string | number 的一种类型

二、typescript 函数类型

函数类型也可以使用联合类型。例如下面这个函数:

function printId(id: number | string) {
    console.log("ID是:" + id.toString());
}

这里的参数 id 可以是数字或者字符串类型。我们也可以使用类型别名来简化代码:

type IdType = number | string;

function printId(id: IdType) {
    console.log("ID是:" + id.toString());
}

这里使用了类型别名 IdType 来表示联合类型,可以使代码更加简洁易懂。

三、typescript联合类型应用场景

联合类型在许多应用场景中都非常有用。例如,我们可以定义一个函数,接收一个可以是字符串或数组的参数:

function printText(text: string | string[]) {
    if (typeof text === "string") {
        console.log(text.toUpperCase());
    } else {
        console.log(text.join("").toUpperCase());
    }
}

printText("Hello, TypeScript!"); // 输出:HELLO, TYPESCRIPT!
printText(["Hello", "TypeScript!"]); // 输出:HELLOTYPESCRIPT!

这里,我们首先判断参数的类型是否为字符串,如果是,就输出转换成大写的结果;否则,我们将数组中的元素拼接成字符串,并输出转换成大写的结果。

四、typescript 联合类型和动态类型

在 TypeScript 中,联合类型和动态类型是非常常见的,它们可以帮助我们动态的处理一些类型信息。

比如,我们定义了一个变量 arr,它可以是字符串数组或者数字数组:

let arr: (string | number)[] = ["hello", 123];

在这种情况下,我们就可以通过数组下标来动态获取数组元素的类型,例如:

let el1 = arr[0]; // el1 的类型就是 string | number
let el2 = arr[1]; // el2 的类型就是 string | number

这里就充分展示了 TypeScript 动态类型的优势,通过获取类型信息,我们可以更加灵活的处理数据。

五、typescript类型

TypeScript 中有各种不同的类型,比如 string、number、boolean、null、undefined、Symbol 等等。在一些情况下,我们需要使用自定义类型,例如:

type UserType = {
  id: number,
  name: string,
  email: string,
  age?: number // 这里的 ? 表示可选,即 age 可以没有
}

let user: UserType = {
  id: 1,
  name: "Tom",
  email: "tom@example.com"
}

console.log(user.id) // 输出 1
console.log(user.name) // 输出 "Tom"
console.log(user.email) // 输出 "tom@example.com"
console.log(user.age) // 输出 undefined

这里我们定义了一个自定义类型 UserType,来表示一个用户对象,它包含了 id、name、email 和 age 四个属性。

六、typescript枚举类型

枚举类型是 TypeScript 中非常实用的类型,它可以将一些值定义成有限的可选项,例如:

enum OrderStatus {
  Pending = "pending",
  Shipped = "shipped",
  Delivered = "delivered"
}

let status: OrderStatus = OrderStatus.Pending;

if (status === OrderStatus.Pending) {
  console.log("订单状态为待确认");
}

这里我们定义了一个枚举类型 OrderStatus,它有三个可选项:Pending、Shipped 和 Delivered。我们也可以直接使用枚举值,例如 OrderStatus.Pending。

七、typescript类型断言

类型断言可以帮助我们在编译阶段确定变量类型,以避免一些潜在的类型错误。例如:

let strOrNum: string | number;
strOrNum = "hello TypeScript";
let len = (strOrNum as string).length;

console.log(len); // 输出 17

这里我们使用了类型断言,来确定 strOrNum 是一个字符串类型,然后获取字符串的长度。

八、typescript 类型推断

TypeScript 可以根据变量类型的使用上下文自动推断出变量类型。例如:

let x = 12;
let y = "hello TypeScript";

console.log(typeof x); // 输出 "number"
console.log(typeof y); // 输出 "string"

这里我们没有明确指定变量类型,但 TypeScript 可以根据后续的使用情况自动推断出变量类型。

九、typescript映射类型

TypeScript 还提供了一种非常强大的映射类型,它可以根据已有类型实时生成新的类型。例如:

interface Person {
    name: string;
    age: number;
}

type ReadonlyPerson = Readonly<Person>;

let person: ReadonlyPerson = {
    name: "Tom",
    age: 20
};

person.age = 21; // 这里会抛出一个编译错误,因为 ReadonlyPerson 类型不允许修改 age 属性

这里我们定义了一个接口 Person,它有两个属性:name 和 age。然后我们使用映射类型 Readonly,来生成一个只读版本的 Person 类型。这样我们就可以避免不小心修改了变量值。

十、typescript高级类型选取

TypeScript 还提供了选取类型的高级特性,它可以根据一些条件来动态选取类型。例如:

interface Square {
    kind: "square";
    size: number;
}

interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}

type Shape = Square | Rectangle;

function area(shape: Shape) {
    if (shape.kind === "square") {
        return shape.size * shape.size;
    } else {
        return shape.width * shape.height;
    }
}

let square: Square = {
    kind: "square",
    size: 10
};

let rectangle: Rectangle = {
    kind: "rectangle",
    width: 10,
    height: 20
};

console.log(area(square)); // 输出 100
console.log(area(rectangle)); // 输出 200

这里我们定义了两个接口 Square 和 Rectangle,表示正方形和矩形。然后我们使用联合类型 Shape 来表示这两种形状,最后定义了一个函数 area,来计算它们的面积。在 area 函数中,我们根据 kind 属性来动态的选择计算面积的方式。

总结

typescript联合类型、枚举类型、类型断言、类型推断、映射类型、高级类型选取等,在 TypeScript 中都非常实用,可以帮助我们更好的处理和管理类型,避免因类型错误引起的 bug。