/// 参数装饰器 import 'reflect-metadata'; const requiredKey = Symbol('paramsIndexs'); function required( target, // 对于静态成员来说是类的构造器,对于实例成员来说是类的原型链 methodName: string, // 方法名称 parameterIndex: number // 描述符 ) { console.info({ target, methodName, parameterIndex }); // 将参数下标信息存入元数据中 const requiredList: number[] = Reflect.getOwnMetadata(requiredKey, target, methodName) || []; requiredList.push(parameterIndex); Reflect.defineMetadata(requiredKey, requiredList, target, methodName); } const isStringKey = Symbol('isStringKey'); function isString(target, methodName, parameterIndex) { const isStringList: number[] = Reflect.getOwnMetadata(isStringKey, target, methodName) || []; isStringList.push(parameterIndex); Reflect.defineMetadata(isStringKey, isStringList, target, methodName); } function validate( target, methodName, // eslint-disable-next-line @typescript-eslint/ban-types descriptor: TypedPropertyDescriptor ) { const requiredList = Reflect.getMetadata(requiredKey, target, methodName) || []; const isStringList = Reflect.getMetadata(isStringKey, target, methodName) || []; console.info({ requiredList }); const oldValue = descriptor.value; descriptor.value = function (...args) { args.forEach((arg, i) => { if (requiredList.includes(i) && arg === undefined) { throw Error(`第${i + 1}个参数为必选`); } if (isStringList.includes(i) && typeof arg !== 'string') { throw Error(`第${i + 1}个参数必须为字符串`); } }); return oldValue.apply(this, args); }; } class Animal { @validate call(@required message, @isString code) { console.log('~~'); } @validate static call(@isString message, @required code) { console.log('~~'); } } const ani = new Animal(); try { ani.call('22', undefined); Animal.call('aa', '22'); } catch (err) { console.info(err.message); } export default Animal;