MST
星途 面试题库

面试题:TypeScript剩余参数与泛型及逆变协变的结合应用

设计一个TypeScript的通用函数,该函数接受一个函数类型的第一个参数,以及使用剩余参数...args接受任意数量的其他参数。此通用函数应能够正确处理传入函数参数的逆变和协变关系,并且能够根据传入的函数类型和参数类型,正确推断返回值类型。请详细说明你的设计思路,并编写完整的代码示例。
26.3万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 为了处理函数参数的逆变和协变关系,我们需要使用泛型。通过泛型来表示传入函数的参数类型和返回值类型。
  2. 利用 infer 关键字在条件类型中推断传入函数的参数类型和返回值类型。
  3. 使用剩余参数 ...args 来接受任意数量的其他参数,并确保这些参数类型与传入函数的参数类型匹配。

代码示例

type FirstArgument<T extends (...args: any[]) => any> = T extends (arg: infer A, ...args: any[]) => any ? A : never;
type RestArguments<T extends (...args: any[]) => any> = T extends (arg: any, ...args: infer R) => any ? R : never;
type ReturnTypeOf<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : never;

function callFunction<T extends (...args: any[]) => any>(func: T, ...args: [...[FirstArgument<T>], ...RestArguments<T>]): ReturnTypeOf<T> {
    return func.apply(null, args);
}

// 示例使用
function add(a: number, b: number): number {
    return a + b;
}

const result = callFunction(add, 1, 2);
console.log(result); // 输出: 3

在上述代码中:

  1. FirstArgument 类型别名用于推断传入函数的第一个参数类型。
  2. RestArguments 类型别名用于推断传入函数除第一个参数外的其他参数类型。
  3. ReturnTypeOf 类型别名用于推断传入函数的返回值类型。
  4. callFunction 函数接受一个函数 func 和剩余参数 ...args,并确保参数类型匹配,同时正确返回函数执行结果,其类型与传入函数的返回值类型一致。