终于搞懂啦!ts泛型是这样使用的呀

简介: 使用泛型可以编写通用的函数或类,以适应多种类型的数据。例如,Array 类型提供了通用的泛型数组容器,可以用于存储不同类型的元素。

应用场景

(Generics)在 TypeScript 中具有广泛的应用场景,它可以增加代码的可重用性、类型安全性和灵活性。以下是泛型常见的应用场景:

  1. 创造可复用的函数或类:使用泛型可以编写通用的函数或类,以适应多种类型的数据。例如,Array 类型提供了通用的泛型数组容器,可以用于存储不同类型的元素。
function printArray<T>(arr: T[]): void {
  for (let item of arr) {
    console.log(item);
  }
}
printArray([1, 2, 3]); // 打印数组元素
printArray(['a', 'b', 'c']); // 打印字符串数组元素
  1. 在集合类型中指定元素类型:通过使用泛型可以定义集合类型,指定其中元素的类型。例如,可以使用泛型参数 <T> 来声明一个泛型数组类型。
type MyArray<T> = T[];
const numbers: MyArray<number> = [1, 2, 3];
const strings: MyArray<string> = ['a', 'b', 'c'];
  1. 创建类型安全的数据结构:泛型可以用于定义类型安全的数据结构,例如栈(Stack)、队列(Queue)等。
class Stack<T> {
  private elements: T[] = [];
  push(element: T): void {
    this.elements.push(element);
  }
  pop(): T | undefined {
    return this.elements.pop();
  }
}
const stack = new Stack<number>();
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.pop()); // 输出 3
console.log(stack.pop()); // 输出 2
  1. 在 React 中编写可复用组件:泛型可以用于编写通用的高阶组件(Higher-order Components,HOC)。HOC 是一个接受一个组件作为参数并返回一个新组件的函数。通过使用泛型,可以使 HOC 更加灵活,适用于不同类型的组件。
function withLoading<T>(Component: React.ComponentType<T>) {
  return function WithLoading(props: T) {
    // 添加 loading 逻辑
    return <Component {...props} />;
  };
}
const MyComponent = withLoading(SomeComponent); // 使用泛型为 SomeComponent 添加 Loading 功能
  1. 创建可扩展的抽象函数或类:通过泛型可以创建可扩展的抽象函数或类,以便其他开发人员可以通过扩展泛型类型参数来添加额外的功能。

泛型约束(Generic Constraints)

用于限制泛型类型参数的类型范围。通过使用泛型约束,可以指定传递给泛型的类型参数必须满足特定的条件,从而增加代码的类型安全性。

以下是几种常见的情况,可以考虑使用泛型约束:

  1. 限制类型参数必须具有某种属性或方法:有时候我们需要确保泛型类型参数包含特定的属性或方法。例如,我们想写一个函数来获取数组的第一个元素,但不确定数组中元素的类型。这时可以使用泛型约束来约束类型参数必须具有 length 属性和索引访问方法,以确保参数是一个数组类型:
function getFirstElement<T extends ArrayLike<any>>(arr: T): T[number] | undefined {
  return arr.length > 0 ? arr[0] : undefined;
}
const result = getFirstElement([1, 2, 3]); // result 的类型为 number
  1. 将泛型类型参数约束为特定的类型或类型范围:有时候我们需要限制泛型类型参数必须是某个特定类型或满足某个类型范围。例如,我们想写一个函数,接受两个参数并返回它们的和,但限制参数必须是数字类型:
function add<T extends number>(a: T, b: T): T {
  return a + b;
}
const result = add(2, 3); // result 的类型为 number

在上述例子中,使用 extends number 泛型约束,确保 ab 的类型参数必须是数字类型。

  1. 使用多个泛型类型参数之间的关系:有时候我们需要在泛型类型参数之间建立关系,例如一个类型参数必须是另一个类型参数的子类型。这种情况下,我们可以使用泛型约束来描述关系。
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
const person = {
  name: 'John',
  age: 30,
};
const name = getProperty(person, 'name'); // name 的类型为 string
const age = getProperty(person, 'age'); // age 的类型为 number

在上述例子中,使用 K extends keyof T 泛型约束,确保 key 的类型参数是对象 T 的键名之一,从而确保获取属性值的键名在对象上有效。

总而言之,使用泛型约束可以在泛型代码中增加类型的限制和约束,提高代码的类型安全性和可读性。泛型约束使得泛型类型参数更加灵活和有用。

相关文章
|
5月前
|
算法 Java API
技术好文:TS中的泛型
技术好文:TS中的泛型
25 0
|
JavaScript
对TS里泛型的理解
对TS里泛型的理解
65 1
|
存储 JavaScript 容器
面试题-TS(六):TypeScript 中的泛型是什么?
在TypeScript中,泛型(Generics)是一种强大的特性,它允许我们在编写可重用的代码时增加灵活性。泛型使得我们可以编写不特定数据类型的代码,从而提高代码复用性和可读性。
|
JavaScript
面试题-TS(四):如何在 TypeScript 中使用类和继承?
在TypeScript中,类是一种重要的概念,它允许我们使用面向对象的编程风格来组织和管理代码。类提供了一种模板,用于创建具有相同属性和行为的对象。通过继承,我们可以创建类之间的层次结构,实现代码的重用和扩展。
|
JavaScript 编译器
面试题-TS(三):TypeScript 中的接口是什么?它们有什么作用?
在TypeScript中,接口是一种用于定义对象属性和行为的工具。它们充当了代码之间的契约,描述了对象应该具有的属性和方法。通过使用接口,我们可以提供更好的类型检查、模块化和代码复用。
ts重点学习1-泛型得基本使用
ts重点学习1-泛型得基本使用
76 0
ts重点学习1-泛型得基本使用
ts重点学习73-泛型的基本使用
ts重点学习73-泛型的基本使用
79 0
ts重点学习73-泛型的基本使用