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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 13:35:17