如何在TypeScript装饰器中自动获取类及属性类型作为泛型参数?
Angular @Watch装饰器自动推导类与属性类型实现方案
完全可以实现无需手动传递泛型参数的自动类型推导,利用TypeScript的装饰器类型推断机制和类型工具就能达成目标。以下是具体实现方案:
核心实现思路
- 调整装饰器的泛型定义,将泛型参数绑定到属性装饰器的目标类原型和属性名上,让TypeScript自动从这两个值推断出类类型和属性类型
- 修正回调函数的类型约束,确保
this自动指向当前类实例,last/current自动匹配被装饰属性的类型 - 保留原有的深度监听逻辑,仅优化类型推导部分
修改后的@Watch装饰器代码
interface CallbackFunction<ThisType, WatchedType> { (this: ThisType, last: WatchedType, current: WatchedType, firstChange: boolean): void; } // 装饰器工厂函数,返回属性装饰器 export function Watch<T extends object, K extends keyof T>( path: string, cb: CallbackFunction<T, T[K]> ) { // 实际的属性装饰器,泛型T为类的实例类型,K为属性名 return function (target: T, key: K) { // 保存原有的ngDoCheck方法 const originalNgDoCheck = target.ngDoCheck; target.ngDoCheck = function (this: T) { // 执行原有ngDoCheck逻辑 if (originalNgDoCheck) { originalNgDoCheck.call(this); } // 你的深度监听逻辑(示例框架) const currentValue = this[key]; const lastValue = currentValue; // 替换为实际旧值存储逻辑 const isFirst = false; // 替换为实际首次变更判断逻辑 // 调用回调,自动绑定类型正确的this与参数 cb.call(this, lastValue, currentValue, isFirst); }; }; }
理想用法示例(无需手动传泛型)
@Component({ /* ... */ }) export class AppComp { @Watch('a.b.c', function(last, current, firstChange) { // this 自动推导为 AppComp 类型 // last/current 自动推导为 { a: { b: { c: string } } } 类型 console.log(this.prop.a.b.c); // 类型安全 console.log(last.a.b.c); // 类型安全 }) prop = { a: { b: { c: 'Hello' } } }; }
关键说明
- 泛型自动推导:TypeScript会根据装饰器应用的
target(AppComp的原型)和key('prop'),自动推断出T为AppComp,T[K]为属性prop的类型 - this类型绑定:回调函数使用普通函数而非箭头函数,确保
this指向类实例,同时通过CallbackFunction的this: ThisType约束,让TypeScript识别this的类型 - 兼容性:该实现完全兼容Angular的
ngDoCheck生命周期钩子,不会破坏原有组件逻辑
内容的提问来源于stack exchange,提问作者LittleSaya
相关产品推荐
相关产品推荐

