实现Parameters

83 阅读1分钟

题目描述 🎯

实现内置的Parameters<T>类型,提取函数类型T的参数类型构成的元组类型。

题目分析 📝

// 期望结果示例:
type T1 = Parameters<(a: string, b: number) => void>; // [string, number]
type T2 = Parameters<() => void>; // []

解题思路 💡

  1. 需要使用条件类型来判断泛型T是否是函数类型。
  2. 使用infer关键字推断函数参数类型。
  3. 处理特殊情况(非函数类型)。

代码实现 ⌨️

type MyParameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never

解题详解 🔍

  1. 类型参数解析
T extends (...args: any) => any // 限制T必须是函数类型
infer P                         // 提取参数类型列表
  1. 实现步骤解析
// 步骤1:使用条件类型判断
T extends (...args: infer P) => any

// 步骤2:如果是函数类型,返回推断的参数类型
? P

// 步骤3:如果不是函数类型,返回 never
: never

测试示例

type MyParameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never

// 测试1:普通函数
type Test1 = MyParameters<(x: string, y: number) => void>
// 结果:string, number]
// 解析:推断出参数类型列表 [string, number]

// 测试2:无参数函数
type Test2 = MyParameters<() => string>;
// 结果:[]
// 解析:空参数列表

相关题目练习

1️. 实现ReturnType(获取函数返回值类型)

type MyReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never

// 测试
type TestReturn = MyReturnType<() => string>; // string
  1. 实现FirstParameter(获取第一个参数类型)
type FirstParameter<T extends (...args: any) => any> = T extends (first: infer F, ...args: any) => any ? F : never;

// 测试
type TestFirst = FirstParameter<(a: string, b: number) => void>; // string
  1. 实现LastParameter(获取最后一个参数类型)
type LastParameter<T extends (...args: any[]) => any> = 
  T extends (arg: infer First) => any 
    ? First 
    : T extends (...args: [...infer _, infer Last]) => any 
      ? Last 
      : never;
// 测试
type TestLast = LastParameter<(a: string, b: number) => void>; // number

// 最要注意的是我们需要处理只有一个参数的情况