1 在Typecript 中什么是泛型
泛型是 TypeScript 中非常重要的概念之一,它允许我们在定义函数、类和接口时使用一个或多个类型参数来表示类型的未知部分,从而增加代码的复用性和灵活性。
简单来说,泛型就是一种参数化的类型,可以在函数或类定义时指定一个或多个类型参数,这些参数可以用来定义函数参数类型、返回值类型、类成员类型等。例如:
function mingslFn<T>(arg: T): T {
return arg;
}
let result = mingslFn<string>('hello'); // T 的类型为 string
console.log(result);//"hello"
在这个例子中,mingslFn 函数使用泛型 <T> 来表示参数类型和返回值类型,这样就可以让函数接受任意类型的参数并返回相同类型的结果。
在使用泛型时,可以使用任意标识符作为泛型参数名,例如 T、U、V 等,一般使用单个大写字母表示泛型参数,以便和普通变量进行区分。
总之,泛型是 TypeScript 中非常重要的概念,它可以大大提高代码的复用性和灵活性,特别是在处理复杂数据结构或接口时,可以让代码更加简洁、易读和可维护。
2 在TypeScript 中使用泛型接口
在 TypeScript 中,我们可以使用泛型接口来定义一个可以接受不同类型参数的接口。泛型接口可以让我们在编写代码时决定使用哪些类型作为参数。
下面是一个示例,演示如何在 TypeScript 中定义和使用泛型接口:
interface DataResult<T> {
code: number;
data: T;
message:string;
}
interface Page{
totalElements:number,
size:number,
content:Product[]
}
interface Product{
id:number,
name:string,
price:number
}
/**
* 返回商品的分页数据
*/
let result:DataResult<Page>={
code:0,
data:{
totalElements:2,
size:10,
content:[
{
id:1,
name:'TS',
price:9.99
},
{
id:2,
name:'JS',
price:9.99
}
]
},
message:'Success'
}
console.log(result);
/**
* 返回单个商品数据
*/
let result1:DataResult<Product>={
code:0,
message:'Success',
data:{
id:1,
name:'TS',
price:9.99
}
}
console.log(result1);
使用泛型接口可以让代码更加灵活和通用,能够处理不同类型的数据,并且可以提高代码的复用性。
3 在TypeScript 中使用泛型类
在 TypeScript 中,泛型类可以帮助我们实现具有通用性的代码,尤其是在编写数据结构或算法的时候,使用泛型类可以减少代码的重复性。
以下是实战一个通用队列,展示了如何使用泛型类来实现一个栈数据结构:
class Queue<T> {
private items: T[];
constructor() {
this.items = [];
}
push(item: T) {
this.items.push(item);
}
pop(): T|undefined {
return this.items.shift();
}
size(): number {
return this.items.length;
}
}
let stringQueue= new Queue<string>();
stringQueue.push("TS");
stringQueue.push("JS");
console.log(stringQueue.pop()); // "TS"
console.log(stringQueue.pop()); // "TS"
console.log(stringQueue.pop()); // undefined
console.log(stringQueue.size()); // 0
let numberQueue = new Queue<number>();
numberQueue.push(1);
numberQueue.push(2);
console.log(numberQueue.pop()); // 1
console.log(numberQueue.size()); // 1
在这个例子中,我们定义了一个泛型类 Queue<T>,它具有三个方法:push、pop 和 size。在构造函数中,我们初始化了一个 items 数组,用于存储队列中的元素。
我们可以使用 stringQueue 和 numberQueue 两个实例来分别创建一个字符串队列和一个数字队列。通过调用 push 和 pop 方法,我们可以将元素写入队列中并从队列中弹出元素。
需要注意的是,使用泛型类时需要为泛型类型参数 T 指定具体的类型。在上面的示例中,我们为 stringQueue 和 numberQueue 分别指定了 string 和 number 类型。
总之,泛型类是 TypeScript 中非常强大和通用的特性。它可以帮助我们编写出更加灵活和可复用的代码,特别是在编写数据结构和算法等通用性较强的代码时,使用泛型类可以大大提高我们的编码效率和代码质量。
4 在TypeScript 中使用泛型约束
泛型约束是 TypeScript 中非常重要的一个概念,它可以帮助我们更好地控制泛型类型的范围和行为。在 TypeScript 中,我们可以使用 extends 关键字来约束泛型类型的范围,例如:
interface User {
userName: string;
age: number;
}
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let user: User = { userName: "xiaohuo", age: 18 };
console.log(getProperty(user, "userName")); // 输出 "xiaohuo"
console.log(getProperty(user, "age")); // 输出 18
console.log(getProperty(user, "gender")); // 报错,因为 "gender" 不是 User 类型的属性
在上面的代码中,我们定义了一个 User 接口,它有 userName 和 age 两个属性。然后,我们定义了一个泛型函数 getProperty,它有两个泛型参数 T 和 K。其中,泛型参数 T 是对象类型,泛型参数 K 是 T 类型的属性名类型。在函数体中,我们使用 obj[key] 返回对象 obj 的属性值。由于泛型参数 K 受到了 keyof T 的约束,所以我们可以放心地使用 obj[key],而不必担心会访问到对象中不存在的属性。
总之,泛型约束是 TypeScript 中非常重要的一个概念,它可以让我们更好地控制泛型类型的范围和行为,提高代码的可读性和可维护性。