TypeScript类原型属性遍历问题:装饰器遍历失效解决方案咨询
解决TypeScript类装饰器遍历原型属性的问题
核心问题出在:TypeScript编译后的类实例方法默认是不可枚举的,for...in循环只会遍历对象的可枚举属性,所以你的循环块根本跑不起来。但直接通过属性名访问时,不管属性是否可枚举都能拿到,所以硬编码的方式能正常工作。
修复方案
换用Object.getOwnPropertyNames()获取类原型上的所有自有属性(包括不可枚举的方法),再过滤掉构造函数后处理方法:
export const controller = (pathPrefix: string) => { return function (target: Function) { const proto = target.prototype; Object.getOwnPropertyNames(proto).forEach(key => { // 跳过类的构造函数 if (key === 'constructor') return; const routeHandler = proto[key]; const path = Reflect.getMetadata("path", proto, key); if (path) { controllerRoute.get(`${pathPrefix}${path}`, routeHandler); } }); } }
如果你的项目里有用到Symbol类型的方法名,也可以用Reflect.ownKeys(),它能返回所有类型的自有属性键:
export const controller = (pathPrefix: string) => { return function (target: Function) { const proto = target.prototype; Reflect.ownKeys(proto).forEach(key => { // 跳过构造函数和Symbol类型键 if (key === 'constructor' || typeof key === 'symbol') return; const routeHandler = proto[key as string]; const path = Reflect.getMetadata("path", proto, key as string); if (path) { controllerRoute.get(`${pathPrefix}${path}`, routeHandler); } }); } }
额外说明
- ES6规范里,类的原型方法默认就是不可枚举的,TypeScript编译后遵循这个规范,这就是
for...in拿不到方法的原因。 - 要确保你的
@get装饰器是用Reflect.defineMetadata来存储路径信息的,不然类装饰器里拿不到对应的元数据。
内容的提问来源于stack exchange,提问作者Farbod Shabani
相关产品推荐
相关产品推荐

