软件教程 2025年08月6日
0 收藏 0 点赞 694 浏览 4004 个字
摘要 :

文章目录 引言 概念 泛型的使用 1. 函数中使用泛型 2. 类型别名中使用泛型 3. 接口中使用泛型 4. 类中使用泛型 泛型约束与多泛型 1. 泛型约束 2. 多泛型 示例 总结 ……




  • 引言
  • 概念
  • 泛型的使用
    • 1. 函数中使用泛型
    • 2. 类型别名中使用泛型
    • 3. 接口中使用泛型
    • 4. 类中使用泛型
  • 泛型约束与多泛型
    • 1. 泛型约束
    • 2. 多泛型
  • 示例
  • 总结

本篇文章主要讲解TypeScript基础:泛型,让我们来详解以下该知识点!

引言

在编程中,我们经常会遇到需要处理不同类型数据的情况。为了提高代码的复用性和灵活性,TypeScript引入了泛型的概念。泛型可以让我们在定义函数、类或接口时,不预先指定具体的类型,而是在使用时再指定类型。本文将详细介绍TypeScript中泛型的使用方法和技巧。

概念

泛型是一种参数化类型的方式,它可以用来创建可重用的组件。通过使用泛型,我们可以在定义函数、类或接口时不预先指定具体的类型,而是在使用时再指定类型。这样可以增加代码的灵活性和复用性。

泛型的使用

在函数、类型别名、接口和类中使用泛型可以增加代码的灵活性和重用性。下面详细介绍如何在这些场景中使用泛型,并提供相应的示例。

1. 函数中使用泛型

函数可以使用泛型来接收不同类型的参数,并返回相应的结果。可以通过在函数名后面使用尖括号()来定义泛型参数,并在函数体内使用该参数。

function identity<T>(arg: T): T {
  return arg;
}

let result = identity<string>(\"Hello\");
console.log(result);  // 输出:Hello

let result2 = identity<number>(123);
console.log(result2);  // 输出:123

2. 类型别名中使用泛型

类型别名可以用来定义复杂的类型,包括泛型类型。可以通过在类型别名后面使用尖括号()来定义泛型参数,并在类型定义中使用该参数。

type Pair<T> = {
  first: T;
  second: T;
};

let pair: Pair<number> = { first: 1, second: 2 };
console.log(pair);  // 输出:{ first: 1, second: 2 }

let pair2: Pair<string> = { first: \"hello\", second: \"world\" };
console.log(pair2);  // 输出:{ first: \'hello\', second: \'world\' }

3. 接口中使用泛型

接口可以使用泛型来定义灵活的类型。可以通过在接口名后面使用尖括号()来定义泛型参数,并在接口定义中使用该参数。

interface Box<T> {
  value: T;
}

let box: Box<number> = { value: 123 };
console.log(box);  // 输出:{ value: 123 }

let box2: Box<string> = { value: \"hello\" };
console.log(box2);  // 输出:{ value: \'hello\' }

4. 类中使用泛型

类可以使用泛型来定义灵活的属性和方法。可以通过在类名后面使用尖括号()来定义泛型参数,并在类定义中使用该参数。

class Queue<T> {
  private elements: T[] = [];

  enqueue(element: T): void {
    this.elements.push(element);
  }

  dequeue(): T | undefined {
    return this.elements.shift();
  }

  isEmpty(): boolean {
    return this.elements.length === 0;
  }

  size(): number {
    return this.elements.length;
  }
}

let queue = new Queue<number>();

queue.enqueue(1);
queue.enqueue(2);

console.log(queue.dequeue());  // 输出:1
console.log(queue.size());  // 输出:1

泛型约束与多泛型

泛型约束和多泛型是在使用泛型时的一些高级技巧,可以进一步限制泛型的类型范围和增加灵活性。下面详细介绍泛型约束和多泛型,并提供相应的示例说明。

1. 泛型约束

泛型约束可以限制泛型参数必须满足某些条件,例如必须是某个基类的子类、必须实现某个接口等。可以使用 extends 关键字来定义泛型约束。

interface Lengthwise {
  length: number;
}

function loggingIdentity<extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

loggingIdentity(\"hello\"); // 输出:5
loggingIdentity([1, 2, 3]); // 输出:3
loggingIdentity({ length: 10, value: 3 }); // 输出:10

2. 多泛型

可以同时定义多个泛型参数,用逗号分隔。多个泛型参数可以相互之间有关联,也可以完全独立。

function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

let mergedObj = merge({ name: \"John\" }, { age: 30 });

console.log(mergedObj.name); // 输出:John
console.log(mergedObj.age); // 输出:30

在上面的示例中,merge 函数接收两个参数,一个是类型为 T 的对象 obj1,另一个是类型为 U 的对象 obj2。函数返回的类型是 T & U,表示返回的对象同时具有 TU 类型的属性。

需要注意以下几点:

  • 泛型约束使用 extends 关键字来定义,可以约束泛型参数必须满足某些条件。
  • 泛型约束可以应用于泛型函数、泛型类和泛型接口。
  • 多个泛型参数可以相互之间有关联,也可以完全独立。
  • 在使用多泛型时,需要注意传入的参数类型和返回值类型要与泛型参数相匹配,否则可能会导致编译错误或运行时错误。

示例

开发一个字典类(Dictionary),字典中会保存键值对的数据

键值对数据的特点:

  • 键(key)可以是任何类型,但不允许重复
  • 值(value)可以是任何类型
  • 每个键对应一个值
  • 所有的键类型相同,所有的值类型相同
export type CallBack<T, U> = (key: T, val: U) => void

export class Dictionary<K, V> {
  private keys: K[] = []
  private values: V[] = []

  get size() {
    return this.keys.length
  }

  set(key: K, val: V) {
    const i = this.keys.indexOf(key)
    if (i < 0) {
      this.keys.push(key)
      this.values.push(val)
    } else {
      this.values[i] = val
    }
  }

  forEach(callback: CallBack<K, V>) {
    this.keys.forEach((k, i) => {
      const v = this.values[i]
      callback(k, v)
    })
  }

  has(key: K) {
    return this.keys.includes(key)
  }

  delete(key: K) {
    const i = this.keys.indexOf(key)
    if (i === -1) {
      return
    }
    this.keys.splice(i, 1)
    this.values.splice(i, 1)
  }
}

这个泛型类和泛型类型别名可以实现一个通用的字典数据结构。可以根据需要传入不同类型的键和值来创建字典对象,并使用提供的方法进行操作。例如:

const dict = new Dictionary<string, number>();

dict.set(\"one\", 1);
dict.set(\"two\", 2);
dict.set(\"three\", 3);

console.log(dict.size); // 输出:3

dict.forEach((key, value) => {
  console.log(key, value);
});
// 输出:
// one 1
// two 2
// three 3

console.log(dict.has(\"two\")); // 输出:true

dict.delete(\"two\");
console.log(dict.has(\"two\")); // 输出:false

需要注意的是,在使用泛型类和泛型类型别名时,可以根据实际需求传入不同的类型参数,以适应不同的数据类型。

总结

泛型是TypeScript中非常重要的特性之一,它可以让我们在定义函数、类或接口时不预先指定具体的类型,而是在使用时再指定类型。通过使用泛型,我们可以增加代码的灵活性和复用性。在函数中使用泛型时,可以通过传入具体的类型参数来调用函数。在类型别名、接口、类中使用泛型时,可以在定义时指定类型参数,并在使用时传入具体的类型。同时,我们还可以对泛型进行约束以确保传入的类型满足某些条件。

使用泛型的一些技巧和需要注意的点如下:

  • 可以同时定义多个泛型参数,例如 function foo(arg1: T, arg2: U): void { ... }
  • 可以在泛型参数上使用约束,例如 function foo(arg: T): void { ... },其中 SomeType 是一个已知的类型。
  • 可以在泛型参数上使用默认类型,例如 function foo(arg: T): void { ... },其中 SomeType 是一个已知的类型。
  • 在使用泛型时,可以显式指定泛型参数的类型,也可以让编译器自动推断泛型参数的类型。
  • 在使用泛型时,需要注意传入的参数类型和返回值类型要与泛型参数相匹配,否则可能会导致编译错误或运行时错误。

以上就是TypeScript基础:泛型详解的全部内容,学习愉快哦!

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/6369.html

管理员

相关推荐
2025-08-06

文章目录 一、Promise基础回顾 二、Promise 与 axios 结合使用场景及方法 (一)直接返回 axios …

269
2025-08-06

文章目录 一、模块初始化时的内部机制 二、常见导出写法的差异分析 (一)写法一:module.exports…

107
2025-08-06

文章目录 一、ResizeObserver详解 (一)ResizeObserver是什么 (二)ResizeObserver的基本用法 …

683
2025-08-06

文章目录 一、前期准备工作 (一)下载相关文件 (二)安装必要工具 二、处理扣子空间生成的文件…

338
2025-08-06

文章目录 一、官方文档 二、自动解包的数据类型 ref对象:无需.value即可访问 reactive对象:保持…

371
2025-08-06

文章目录 一、Hooks的工作原理 二、在if语句中使用Hook会出什么岔子? 三、React官方的Hook使用规…

843
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号