TypeScript中如何获取类构造函数参数名组成的联合类型?
TypeScript 获取类构造函数参数名联合类型实现方案
首先明确核心限制:使用原生ConstructorParameters<T>拿到的构造函数参数元组是带标签元组,比如示例中拿到的[name: string, age: number],其中的name/age属于元组的标签元数据,默认通过索引访问只能拿到参数类型(比如ConstructorParameters<typeof Person>[0]是string),标签不会直接暴露为可访问的类型成员,需要通过类型模式匹配提取。
通用工具类型实现
以下工具类型兼容TS 4.0及以上版本(具名元组是TS4.0正式支持的特性),可以直接提取任意普通类、抽象类的构造函数参数名联合类型:
type GetConstructorParamNames<T extends abstract new (...args: any) => any> = ConstructorParameters<T> extends infer Params ? Params extends readonly any[] ? { [K in keyof Params]: K extends `${number}` ? (x: (...args: Record<K, any>) => void) => void extends (x: (...args: { [_ in K]: infer Name extends string }) => void) => void ? Name : never : never }[number] : never : never
使用示例
针对给出的Person类,使用方式如下:
class Person { constructor(name: string, age: number){} } type PersonCtorParamNames = GetConstructorParamNames<typeof Person>; // 类型计算结果为 'name' | 'age',完全符合需求
特殊场景简化方案
如果构造函数参数使用了TS参数属性(即给参数添加public/private/protected/readonly修饰符,参数会自动成为类的实例属性),不需要编写复杂工具类型,直接取实例类型的键即可:
class User { // 带public修饰符的参数属性 constructor(public id: number, public username: string) {} } type UserParamNames = keyof InstanceType<typeof User>; // 计算结果为 'id' | 'username'
注意事项
- 不要对
ConstructorParameters返回的元组做会擦除标签的类型转换,比如直接映射元组修改值类型、交叉其他对象类型等操作,都会导致参数名标签丢失,无法提取。 - 该方案依赖TS对具名元组标签的内部类型存储,升级TS大版本时如果遇到类型失效,需要对应调整匹配逻辑。
内容的提问来源于stack exchange,提问作者Pavlo
相关产品推荐
相关产品推荐

