如何为动态生成的类实现TypeScript类型定义?
解决方案
方案1:声明合并 + Object.assign(推荐)
这种方式无需手动维护方法列表,TypeScript能自动识别所有动态挂载的方法,同时避免索引类型错误:
import * as User from './user'; export class Database { constructor() { // 批量复制User模块的所有方法到实例 Object.assign(this, User); } } // 通过声明合并,让Database实例继承User模块的全部方法类型 declare module './database' { interface Database extends typeof User {} }
优势:
- 无需添加
@ts-nocheck,彻底解决索引类型报错 - User模块新增方法时,Database的类型会自动同步,无需手动修改
- 类型提示完整,和直接调用User模块方法的体验一致
方案2:类型断言 + 显式方法声明
如果坚持使用循环赋值的方式,可通过类型断言解决索引错误,同时显式声明方法类型:
import * as User from './user'; export class Database { // 显式声明User模块的方法类型,让TypeScript识别 findById!: typeof User.findById; findByName!: typeof User.findByName; constructor() { // 将循环变量断言为User模块的键类型,消除索引any错误 for (const method of Object.keys(User) as Array<keyof typeof User>) { this[method] = User[method]; } } }
注意:此方法需要手动声明每个User模块的方法,适合方法数量较少的场景,新增方法时需同步更新类中的声明。
方案3:挂载到类原型(共享方法)
若希望所有Database实例共享方法(减少内存占用),可将User的方法挂载到类原型上:
import * as User from './user'; export class Database {} // 将User模块的方法挂载到Database原型 Object.assign(Database.prototype, User); // 声明合并让TypeScript识别原型上的方法 declare module './database' { interface Database extends typeof User {} }
使用方式不变,但方法是原型共享的,内存效率更高。
内容的提问来源于stack exchange,提问作者Sebastiaan
相关产品推荐
相关产品推荐

