TypeScript中如何在方法装饰器内直接获取方法参数列表
解决方案
你可以通过两种方式直接获取目标方法的参数列表,完全不需要用正则匹配整个方法体(你当前的正则逻辑存在误判风险:如果方法体内出现名为executionTime的变量,会被误识别为参数存在)。
方案1:原生JS运行时解析(无额外依赖)
所有函数的toString()方法会返回函数的完整源码字符串,你只需要截取第一个(和第一个)之间的内容,即可提取出全部参数名,逻辑如下:
function performanceMetrics() { return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; // 提取参数区段 const fnString = originalMethod.toString(); const paramStartIndex = fnString.indexOf('(') + 1; const paramEndIndex = fnString.indexOf(')', paramStartIndex); const paramSegment = fnString.slice(paramStartIndex, paramEndIndex).trim(); // 拆分得到所有参数名(TS编译后类型标注会被抹除,无需额外处理类型) const paramNames = paramSegment ? paramSegment.split(',').map(param => param.trim().split(/[= :]/)[0]) : []; // 校验参数是否存在 if (!paramNames.includes('executionTime')) { console.log(`方法${propertyKey}缺失必填参数executionTime`); } }; }
这个方案兼容所有TS编译目标,不需要额外安装依赖,普通参数场景下准确率100%。如果你的项目中有解构参数、参数默认值等特殊写法,只需要调整参数名提取的正则逻辑即可适配。
方案2:TS元数据校验(适合需要校验参数类型的场景)
如果需要同时校验executionTime的类型是否为数字,可以开启TS的装饰器元数据能力:
- 安装
reflect-metadata依赖,在项目入口引入 - 在
tsconfig.json中开启以下配置:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } }
- 装饰器中可以直接获取参数类型列表:
import 'reflect-metadata'; function performanceMetrics() { return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) { // 先按方案1的逻辑校验参数名是否存在 const fnString = descriptor.value.toString(); const paramStartIndex = fnString.indexOf('(') + 1; const paramEndIndex = fnString.indexOf(')', paramStartIndex); const paramSegment = fnString.slice(paramStartIndex, paramEndIndex).trim(); const paramNames = paramSegment ? paramSegment.split(',').map(param => param.trim().split(/[= :]/)[0]) : []; const executionTimeIndex = paramNames.indexOf('executionTime'); if (executionTimeIndex === -1) { return console.log(`方法${propertyKey}缺失必填参数executionTime`); } // 校验executionTime的类型是否为number const paramTypes = Reflect.getMetadata('design:paramtypes', target, propertyKey); if (paramTypes[executionTimeIndex] !== Number) { console.log(`方法${propertyKey}的executionTime参数类型必须为number`); } }; }
内容的提问来源于stack exchange,提问作者Brijesh Ahuja
相关产品推荐
相关产品推荐

