返回

TypeScript高阶类型妙用大全,实战篇

前端

TypeScript 高阶类型妙用大全,实战篇

TypeScript 是一种流行且强大的编程语言,它可以帮助我们构建可靠且可维护的前端应用程序。TypeScript 中的高阶类型可以让我们编写更灵活和可复用的代码。在本文中,我们将探讨 TypeScript 高阶类型的一些常见用法以及如何将它们应用于实际项目中。

一、高级类型

交叉类型(&)

交叉类型是将多个类型合并为一个类型。这让我们可以把现有类型组合成一个新的类型,该类型包含所有这些类型的属性和方法。交叉类型使用 & 符号来连接多个类型。

例如,我们可以定义一个 Person 类型,它包含 nameage 两个属性:

type Person = {
  name: string;
  age: number;
};

然后,我们可以定义一个 Employee 类型,它继承了 Person 类型并添加了 salary 属性:

type Employee = Person & {
  salary: number;
};

现在,我们可以使用 Employee 类型来创建员工对象:

const employee: Employee = {
  name: 'John',
  age: 30,
  salary: 100000
};

联合类型(|)

联合类型是允许一个值可以是多个类型之一的类型。这让我们可以定义一个类型,它可以接受多种不同的值。联合类型使用 | 符号来分隔多个类型。

例如,我们可以定义一个 Shape 类型,它可以是 CircleSquareTriangle 类型之一:

type Shape = Circle | Square | Triangle;

然后,我们可以使用 Shape 类型来定义一个函数,该函数可以接受任何类型的形状:

function drawShape(shape: Shape) {
  // 绘制形状
}

现在,我们可以使用不同的形状类型来调用 drawShape() 函数:

drawShape(new Circle());
drawShape(new Square());
drawShape(new Triangle());

泛型

泛型允许我们定义可以接受任何类型作为参数的函数或类。这让我们可以编写更灵活和可重用的代码。泛型使用尖括号 <> 来定义类型参数。

例如,我们可以定义一个 List 类,它可以存储任何类型的元素:

class List<T> {
  private items: T[] = [];

  add(item: T) {
    this.items.push(item);
  }

  get(index: number): T {
    return this.items[index];
  }
}

现在,我们可以使用 List 类来创建存储不同类型元素的列表:

const numbers = new List<number>();
numbers.add(1);
numbers.add(2);
numbers.add(3);

const strings = new List<string>();
strings.add('Hello');
strings.add('World');
strings.add('!');

映射类型

映射类型允许我们创建新的类型,它是从现有类型的属性创建的。这让我们可以轻松地转换对象的属性类型。映射类型使用 {} 符号来定义新的类型。

例如,我们可以定义一个 Person 类型,它包含 nameage 两个属性:

type Person = {
  name: string;
  age: number;
};

然后,我们可以定义一个 PersonWithOptionalAge 类型,它从 Person 类型派生而来,但 age 属性是可选的:

type PersonWithOptionalAge = {
  [P in keyof Person]?: Person[P];
};

现在,我们可以使用 PersonWithOptionalAge 类型来定义一个函数,该函数可以接受具有可选 age 属性的人员对象:

function greetPerson(person: PersonWithOptionalAge) {
  console.log(`Hello, ${person.name}!`);
}

现在,我们可以使用 PersonWithOptionalAge 类型来调用 greetPerson() 函数:

greetPerson({ name: 'John' });
greetPerson({ name: 'Jane', age: 30 });

条件类型

条件类型允许我们创建新的类型,它是基于另一个类型的属性或值。这让我们可以根据某些条件来更改类型的属性或值。条件类型使用 extends? 符号来定义新的类型。

例如,我们可以定义一个 Person 类型,它包含 nameage 两个属性:

type Person = {
  name: string;
  age: number;
};

然后,我们可以定义一个 IsAdult 类型,它是一个布尔类型,表示一个人是否成年:

type IsAdult = Person['age'] extends 18 ? true : false;

现在,我们可以使用 IsAdult 类型来定义一个函数,该函数可以检查一个人是否成年:

function isAdult(person: Person): IsAdult {
  return person.age >= 18;
}

现在,我们可以使用 isAdult() 函数来检查一个人是否成年:

const john = { name: 'John', age: 30 };
const jane = { name: 'Jane', age: 16 };

console.log(isAdult(john)); // true
console.log(isAdult(jane)); // false

二、实战应用

开发一个简单的购物车应用程序

在购物车应用程序中,我们可以使用高级类型来定义购物车的类型,该类型可以包含多种类型的商品。我们可以使用联合类型来定义商品的类型,使用交叉类型来定义购物车的类型,并使用泛型来定义购物车的操作方法。

例如,我们可以定义一个 Product 类型,它包含 namepricequantity 三个属性:

type Product = {
  name: string;
  price: number;
  quantity: number;
};

然后,我们可以定义一个 ShoppingCart 类型,它是一个数组,其中包含 Product 类型的商品:

type ShoppingCart<T extends Product> = T[];

现在,我们可以使用 ShoppingCart 类型来定义一个函数,该函数可以计算购物车的总价:

function calculateTotalPrice<T extends Product>(cart: ShoppingCart<T>): number {
  let totalPrice = 0;
  for (const product of cart) {
    totalPrice += product.price * product.quantity;
  }
  return totalPrice;
}

现在,我们可以使用 calculateTotalPrice() 函数来计算购物车的总价:

const cart: ShoppingCart<Product> = [
  { name: 'Apple', price: 1.00, quantity: 3 },
  { name: 'Orange', price: 2.00, quantity: 2 },
  { name: 'Banana', price: 3.00, quantity: 1 }
];

console.log(calculateTotalPrice(cart)); // 11.00

构建一个简单的博客系统

在博客系统中,我们可以使用高级类型来定义博文的类型,该类型可以包含多种类型的属性。我们可以使用联合类型来定义博文的类型,使用交叉类型来定义博文的属性,并使用泛型来定义博文的操作方法。

例如,我们可以定义一个 Post 类型,它包含 titlecontentauthor 三个属性:

type Post = {
  title: string;
  content: string;
  author: string;
};

然后,我们可以定义一个 Blog 类型,它是一个数组,其中包含 Post 类型的博文:

type Blog<T extends Post> = T[];

现在,我们可以使用 Blog 类型来定义一个函数,该函数可以获取博文的列表:

function getPosts<T extends Post>(blog: Blog<T>): T[] {
  return blog;
}

现在,我们可以使用 getPosts() 函数来获取博文的列表:

const blog: Blog<Post> = [
  { title: 'Hello World', content: 'This is my first post', author: 'John Doe' },
  { title: 'My Favorite Things', content: 'Here are some of my favorite things', author: 'Jane Doe' },
  { title: 'The Meaning of Life', content: 'What is the meaning of life?', author: 'Bill Smith' }
];

console.log(getPosts(blog));

总结

TypeScript 高阶类型是 TypeScript 中一个强大的工具,它可以帮助我们编写更灵活和可复用的代码。在本文中,我们探讨了 TypeScript 高阶类型的一些常见用法以及如何将它们