十个例子理解TS泛型

88 阅读2分钟

TypeScript 的泛型功能可以帮助我们编写更具可复用性和类型安全性的代码。本文将使用泛型编写十个例子来帮助大家提升对ts泛型的理解程度

  1. 使用泛型实现数组反转
function reverse<T>(arr: T[]): T[] {
  return arr.reverse();
}

const nums = [1, 2, 3, 4, 5];
const reversedNums = reverse(nums);
console.log(reversedNums); // Output: [5, 4, 3, 2, 1]
  1. 使用泛型实现数组去重
function unique<T>(arr: T[]): T[] {
  return Array.from(new Set(arr));
}

const nums = [1, 2, 2, 3, 3, 4, 5, 5];
const uniqueNums = unique(nums);
console.log(uniqueNums); // Output: [1, 2, 3, 4, 5]
  1. 使用泛型实现栈数据结构
class Stack<T> {
  private items: T[] = [];

  push(item: T) {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }
}

const stack = new Stack<number>();
stack.push(1);
stack.push(2);
console.log(stack.pop()); // Output: 2
console.log(stack.pop()); // Output: 1
  1. 使用泛型实现队列数据结构
class Queue<T> {
  private items: T[] = [];

  enqueue(item: T) {
    this.items.push(item);
  }

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

const queue = new Queue<number>();
queue.enqueue(1);
queue.enqueue(2);
console.log(queue.dequeue()); // Output: 1
console.log(queue.dequeue()); // Output: 2
  1. 使用泛型实现对象深度拷贝
function clone<T>(obj: T): T {
  return JSON.parse(JSON.stringify(obj));
}

const person = { name: "John", age: 30 };
const clonedPerson = clone(person);
console.log(clonedPerson); // Output: { name: "John", age: 30 }
  1. 使用泛型实现函数柯里化
function curry<T extends any[], R>(fn: (...args: T) => R): (...args: T) => R | ((...args: T) => R) {
  return function curried(...args: T) {
    if (args.length >= fn.length) {
      return fn(...args);
    } else {
      return (...more: T) => curried(...args, ...more);
    }
  };
}

function sum(a: number, b: number, c: number): number {
  return a + b + c;
}

const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // Output: 6
console.log(curriedSum(1, 2)(3)); // Output: 6
console.log(curriedSum(1, 2, 3)); // Output: 6
  1. 使用泛型实现可重用的表单验证函数
type Validator<T> = (value: T) => boolean;

function required<T>(value: T): boolean {
  return value !== undefined && value !== null && value !== "";
}

function minLength<T extends { length: number
  1. 使用泛型实现函数节流
function throttle<T extends any[]>(fn: (...args: T) => void, delay: number): (...args: T) => void {
  let timer: ReturnType<typeof setTimeout> | undefined;

  return function throttled(...args: T) {
    if (!timer) {
      timer = setTimeout(() => {
        fn(...args);
        timer = undefined;
      }, delay);
    }
  };
}

function log(text: string) {
  console.log(text);
}

const throttledLog = throttle(log, 1000);
throttledLog("Hello");
throttledLog("World");
throttledLog("!");

// Output: "Hello"
// (after 1 second) "World"
// (after 1 second) "!"
  1. 使用泛型实现可组合的函数
type Func<T, R> = (arg: T) => R;

function compose<T, A, R>(fn1: Func<T, A>, fn2: Func<A, R>): Func<T, R> {
  return (arg: T) => fn2(fn1(arg));
}

function add1(x: number): number {
  return x + 1;
}

function double(x: number): number {
  return x * 2;
}

const add1ThenDouble = compose(add1, double);
console.log(add1ThenDouble(3)); // Output: 8
  1. 使用泛型实现可逆函数
type ReversibleFunc<T, R> = {
  forward: (arg: T) => R;
  backward: (arg: R) => T;
};

function createReversibleFunc<T, R>(forward: (arg: T) => R, backward: (arg: R) => T): ReversibleFunc<T, R> {
  return {
    forward,
    backward,
  };
}

const reversibleAdd1 = createReversibleFunc(
  (x: number) => x + 1,
  (x: number) => x - 1
);

console.log(reversibleAdd1.forward(3)); // Output: 4
console.log(reversibleAdd1.backward(4)); // Output: 3

这些示例只是 TypeScript 泛型功能的冰山一角,你可以将泛型用于各种类型和场景,从简单的函数到复杂的数据结构,帮助你编写更具可复用性和类型安全性的代码。