TypeScript 中的高阶函数是非常强大的工具,可以用于创建更灵活、可复用和易于维护的代码。以下是一些实际应用案例,展示了如何在实际项目中使用高阶函数。

1. 日志装饰器

使用高阶函数创建一个日志装饰器,可以记录函数的调用情况。

function logDecorator<T extends (...args: any[]) => any>(
  target: T,
  context: ClassMethodDecoratorContext
) {
  const methodName = String(context.name);
 
  function replacementMethod(this: any, ...args: Parameters<T>): ReturnType<T> {
    console.log(`Calling method ${methodName} with args:`, args);
    const result = target.apply(this, args);
    console.log(`Method ${methodName} returned:`, result);
    return result;
  }
 
  return replacementMethod;
}
 
class Calculator {
  @logDecorator
  add(a: number, b: number): number {
    return a + b;
  }
}
 
const calc = new Calculator();
calc.add(5, 3); // 这将输出日志信息

2. 缓存函数结果

创建一个高阶函数来缓存其他函数的结果,提高性能。

function memoize<T extends (...args: any[]) => any>(fn: T): T {
  const cache = new Map<string, ReturnType<T>>();
 
  return function(this: any, ...args: Parameters<T>): ReturnType<T> {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key)!;
    }
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  } as T;
}
 
const expensiveOperation = memoize((n: number): number => {
  console.log("Calculating...");
  return n * n;
});
 
console.log(expensiveOperation(4)); // 输出: Calculating... 16
console.log(expensiveOperation(4)); // 输出: 16 (从缓存中获取)

3. 函数组合

创建一个函数组合工具,可以将多个函数组合成一个函数。

type Func<T extends any[], R> = (...a: T) => R;
 
function compose<R>(fn1: Func<any, R>, ...fns: Array<Func<any, any>>): Func<any, R> {
  return fns.reduce((prevFn, nextFn) => {
    return value => prevFn(nextFn(value));
  }, fn1);
}
 
// 使用示例
const addOne = (x: number) => x + 1;
const double = (x: number) => x * 2;
const square = (x: number) => x * x;
 
const composedFunction = compose(square, double, addOne);
console.log(composedFunction(3)); // ((3 + 1) * 2)^2 = 64

4. 事件处理中的防抖

创建一个防抖函数,用于限制事件处理函数的调用频率。

function debounce<T extends (...args: any[]) => any>(
  func: T,
  delay: number
): (...args: Parameters<T>) => void {
  let timeoutId: ReturnType<typeof setTimeout>;
 
  return function(this: any, ...args: Parameters<T>) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}
 
// 使用示例
const handleSearch = debounce((query: string) => {
  console.log("Searching for:", query);
  // 执行搜索操作
}, 300);
 
// 在输入框的 onChange 事件中使用
// input.addEventListener('input', (e) => handleSearch(e.target.value));

5. 中间件模式

实现一个简单的中间件系统,用于处理请求或任务。

type Middleware<T> = (data: T) => T | Promise<T>;
 
class MiddlewareChain<T> {
  private middlewares: Middleware<T>[] = [];
 
  use(middleware: Middleware<T>) {
    this.middlewares.push(middleware);
    return this;
  }
 
  async execute(initialData: T): Promise<T> {
    let result = initialData;
    for (const middleware of this.middlewares) {
      result = await middleware(result);
    }
    return result;
  }
}
 
// 使用示例
interface Request {
  body: string;
}
 
const chain = new MiddlewareChain<Request>();
 
chain.use(async (req) => {
  req.body = req.body.toLowerCase();
  return req;
}).use(async (req) => {
  req.body = req.body.replace(/[^a-z0-9]/g, '');
  return req;
});
 
chain.execute({ body: "Hello, World! 123" })
  .then(result => console.log(result.body)); // 输出: helloworld123

这些例子展示了高阶函数在实际应用中的多种用途,包括装饰器、缓存、函数组合、事件处理和中间件模式。这些技术可以帮助你编写更加模块化、可复用和高效的代码。在实际项目中,你可以根据具体需求来调整和扩展这些模式。


Perplexity 生成的答案

TypeScript 中的高阶函数是非常强大和灵活的,它们可以帮助我们编写更抽象和复用代码。以下是一些实际应用案例,展示了高阶函数在 TypeScript 中的使用。

例子 1: 高阶函数用于数据处理

假设我们有一个数组,需要对其进行过滤、映射和排序等操作。我们可以使用高阶函数来封装这些操作,使代码更简洁和可读。

// 高阶函数:过滤器
function filter<T>(arr: T[], predicate: (item: T) => boolean): T[] {
  return arr.filter(predicate);
}
 
// 高阶函数:映射器
function map<T, U>(arr: T[], transform: (item: T) => U): U[] {
  return arr.map(transform);
}
 
// 高阶函数:排序器
function sort<T>(arr: T[], compare: (a: T, b: T) => number): T[] {
  return arr.slice().sort(compare);
}
 
// 示例数据
const numbers = [1, 2, 3, 4, 5];
 
// 使用高阶函数进行数据处理
const result = sort(
  map(
    filter(numbers, x => x % 2 === 0),
    x => x * 2
  ),
  (a, b) => a - b
);
 
console.log(result); // [4, 8, 10]

例子 2: 高阶函数用于日志记录和错误处理

我们可以使用高阶函数来封装日志记录和错误处理逻辑,使得我们的业务代码更清晰。

// 高阶函数:日志记录和错误处理
function logAndCatch<T extends (...args: any[]) => any>(fn: T): T {
  return function (...args: any[]) {
    try {
      const result = fn(...args);
      console.log(`成功执行函数 ${fn.name},返回值为:`, result);
      return result;
    } catch (error) {
      console.error(`函数 ${fn.name} 执行失败,错误为:`, error);
      throw error;
    }
  };
}
 
// 业务函数
const add = logAndCatch((a: number, b: number) => a + b);
 
// 调用业务函数
try {
  const result = add(2, 3);
  console.log(result); // Output: 5
} catch (error) {
  console.error('Caught an error:', error);
}

例子 3: 高阶函数用于函数柯里化

柯里化是一种将多个参数的函数转换为一系列单参数函数的技术。我们可以使用高阶函数来实现柯里化。

// 高阶函数:柯里化
function curry<T extends (...args: any[]) => any>(fn: T): (...args: any[]) => any {
  return function curried(...args: any[]): any {
    if (args.length >= fn.length) {
      return fn(...args);
    } else {
      return function (...nextArgs: any[]): any {
        return curried(...args.concat(nextArgs));
      };
    }
  };
}
 
// 业务函数
const sum = (a: number, b: number, c: number): number => a + b + c;
 
//柯里化函数
const curriedSum = curry(sum);
 
// 调用柯里化函数
console.log(curriedSum(1)(2)(3)); // Output: 6

例子 4: 高阶函数用于缓存结果

我们可以使用高阶函数来缓存函数的结果,以避免重复计算。

// 高阶函数:缓存结果
function memoize<T extends (...args: any[]) => any>(fn: T): T {
  const cache = new Map<string, any>();
  return function (...args: any[]): any {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}
 
// 业务函数
const fibonacci = memoize((n: number): number => {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
});
 
// 调用业务函数
console.log(fibonacci(10)); // Output: 55

这些例子展示了高阶函数在 TypeScript 中的实际应用,包括数据处理、日志记录和错误处理、函数柯里化以及缓存结果等.