You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建由类构造函数必填参数组成的泛型TypeScript对象类型?

解决方案

可以通过组合几个泛型类型来实现需求:先提取构造函数的必填参数元组,再将具名元组转换为对象类型。

// 提取构造函数的所有参数元组(复用TypeScript内置类型)
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;

// 递归过滤元组中的可选参数,仅保留必填参数部分
type RequiredConstructorParams<T extends new (...args: any) => any> = 
  ConstructorParameters<T> extends [...infer RequiredArgs, infer _?] 
    ? RequiredConstructorParams<new (...args: RequiredArgs) => any> 
    : ConstructorParameters<T>;

// 将具名元组转换为对象类型,只保留参数的具名属性
type TupleToNamedObject<T extends readonly any[]> = {
  [K in keyof T as K extends string ? K : never]: T[K];
};

// 最终泛型类型:从类构造函数提取必填参数的对象类型
type ConstructorRequiredArgsObject<T extends new (...args: any) => any> = 
  TupleToNamedObject<RequiredConstructorParams<T>>;

使用示例

针对你提供的Example类:

class Example {
  constructor(
    public readonly foo: string,
    public readonly bar: number,
    public readonly option?: number,
  ) {}
}

// 生成目标类型
type ExampleArgs = ConstructorRequiredArgsObject<typeof Example>;
// 类型结果:{ foo: string; bar: number; }

类型说明

  1. RequiredConstructorParams:利用TypeScript元组的可选元素特性,递归排除元组末尾的可选参数,最终得到仅包含必填参数的元组。因为TypeScript要求函数/构造函数的可选参数必须放在参数列表末尾,所以这个递归逻辑可以准确过滤所有可选参数。

  2. TupleToNamedObject:将具名元组转换为对象类型。构造函数中带public修饰符的参数会成为元组的具名键,这里通过keyof T as K extends string ? K : never筛选出这些具名键,最终生成以参数名为属性名的对象类型。

  3. ConstructorRequiredArgsObject:组合前两个类型,直接输出目标对象类型。

原代码问题说明

你之前的代码生成数组类型的原因是:keyof Args对于元组类型来说包含数字索引(比如0、1)和具名键,所以映射后得到的是带数字索引的类数组对象,而非纯对象类型。同时,代码没有处理可选参数的过滤,所以会保留option这类可选参数的类型。

内容的提问来源于stack exchange,提问作者Johnny Oshika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 15:02:01