TS中泛型的使用 | 青训营

87 阅读2分钟

概述

泛型是一种编程语言特性,它允许我们在定义函数、类、接口等数据结构时使用参数化类型,从而实现更通用、灵活的代码。通过使用泛型,我们能够编写可以适用于多种数据类型的代码,而无需为每种数据类型编写重复的代码。

泛型的应用

泛型在函数中使用

根据参数不同,处理结果不同

const getArray = <T>(times: number, val: T): T[] => {
  let result = [];
  for (let i = 0; i < times; i++) {
    result.push(val);
  }
  return result;
};
getArray(3, "a"); // ['abc','abc','abc'] 当我使用的时候可以确定类型

多个泛型也可以使用于元组交换

function swap<T, U>(tuple: [T, U]): [U, T] {
  return [tuple[1], tuple[0]];
}

const originalTuple: [number, string] = [42, "hello"]; 
const swappedTuple: [string, number] = swap(originalTuple); 
console.log(swappedTuple); // 输出:["hello", 42]

泛型接口的使用

可以定义泛型接口,使其能够适用于多种对象的结构。

// 1) 使用接口的时候确定的类型
type ICallback<T> = (item: T, idx: number) => void;
type IForEach = <T extends string | number>(
  arr: T[],
  callback: ICallback<T>
) => void;

// 2) 在调用函数的时候确定了类型
const forEach: IForEach = (arr, callback) => {
  for (let i = 0; i < arr.length; i++) {
    callback(arr[i], i); // callback 没有执行, 所以无法推导arr[i] = T
  }
};
forEach(["a", "b", "c"], function (item) {
  console.log(item);
});

泛型在类中使用

类接口, 描述类中的属性和方法。 求列表中的最大值 调用的时候可以限制传入的类型

class MyList<T extends number | string> {
  private arr: T[] = [];
  add(val: T) {
    this.arr.push(val);
  }
  getMax(): T {
    let arr = this.arr;
    let max = arr[0];
    for (let i = 0; i < arr.length; i++) {
      let cur = arr[i];
      cur > max ? (max = cur) : void null;
    }
    return max;
  }
}
let list = new MyList();
list.add(1);
list.add(100);

默认泛型

场景就是如果用户不传入类型 我也希望有默认值

type Union<T = string> = T | number;

type t1 = Union;
type t2 = Union<boolean>;

此时type t1 = string | number,type t2 = number | boolean

泛型约束

泛型约束是 TypeScript 中的一种高级技术,允许你定义泛型类型参数的约束条件,以便在操作中保证类型的兼容性和类型安全性。通过泛型约束,你可以限制允许传递给泛型类型参数的数据类型范围,从而确保代码的正确性。 约束传入的泛型类型, A extends B,A是B的子类型.

function handle<T extends number | string>(val: T): T {
  return val;
}
let r1 = handle(123);
let r2 = handle("abc");

上述其他场景也有应用泛型约束,总之,泛型约束是 TypeScript 中的一个重要概念,通过限制泛型类型参数的操作范围,它能够提高代码的类型安全性和可维护性。在实际开发中,泛型约束能够帮助我们编写更强大、更可靠的代码,同时减少潜在的错误。无论是限制特定数据类型的操作范围,还是为泛型接口添加额外功能,泛型约束都是编写高质量代码的有力工具。