TypeScript高阶类型妙用大全,实战篇
2023-09-20 11:51:01
TypeScript 高阶类型妙用大全,实战篇
TypeScript 是一种流行且强大的编程语言,它可以帮助我们构建可靠且可维护的前端应用程序。TypeScript 中的高阶类型可以让我们编写更灵活和可复用的代码。在本文中,我们将探讨 TypeScript 高阶类型的一些常见用法以及如何将它们应用于实际项目中。
一、高级类型
交叉类型(&)
交叉类型是将多个类型合并为一个类型。这让我们可以把现有类型组合成一个新的类型,该类型包含所有这些类型的属性和方法。交叉类型使用 &
符号来连接多个类型。
例如,我们可以定义一个 Person
类型,它包含 name
和 age
两个属性:
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
类型,它可以是 Circle
、Square
或 Triangle
类型之一:
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
类型,它包含 name
和 age
两个属性:
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
类型,它包含 name
和 age
两个属性:
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
类型,它包含 name
、price
和 quantity
三个属性:
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
类型,它包含 title
、content
和 author
三个属性:
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 高阶类型的一些常见用法以及如何将它们