TypeScript中如何正确为接收类和属性对象返回扩展类的函数做类型标注?
TypeScript 类扩展函数的类型标注方案
核心实现
首先我们可以通过泛型约束分别匹配入参的类构造函数、附加属性对象类型,再组合得到返回的新类类型:
// 定义通用类构造类型,保留abstract修饰符可兼容抽象类传入 type Constructor<T = {}> = abstract new (...args: any[]) => T; function extendClassWithProps< T extends Constructor, U extends object >( BaseClass: T, props: U ): T & Constructor<InstanceType<T> & U> { // 函数逻辑实现示例 return class extends BaseClass { constructor(...args: any[]) { super(...args); // 将传入的属性全部挂载到新类实例上 Object.assign(this, props); } } as any; }
类型说明
- 泛型参数
T:约束传入的基类构造函数,InstanceType<T>工具类型可以直接提取基类的实例类型 - 泛型参数
U:约束传入的附加属性对象的类型 - 返回值类型
T & Constructor<InstanceType<T> & U>:保证返回的新类同时保留原基类的静态属性/方法类型,新类的实例也同时包含基类实例的所有成员、以及第二个入参对象的所有属性和方法类型
使用示例
// 测试基类 class User { name: string; constructor(name: string) { this.name = name; } sayHi() { return `Hi ${this.name}`; } } // 测试附加属性对象 const extraProps = { role: 'admin' as const, isActive: true, getRole() { return this.role; } } // 生成扩展后的新类 const ExtendedUser = extendClassWithProps(User, extraProps); // 类型校验完全正常 const user = new ExtendedUser('张三'); console.log(user.name); // 正常读取基类属性 console.log(user.sayHi()); // 正常调用基类方法 console.log(user.role); // 正常读取附加属性 console.log(user.getRole()); // 正常调用附加方法
补充说明
如果附加属性和基类的现有属性同名,TypeScript会自动识别为类型冲突,编译阶段即可抛出错误提示,符合实际使用预期。
内容的提问来源于stack exchange,提问作者lemme
相关产品推荐
相关产品推荐

