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

如何在TypeScript装饰器中自动获取类及属性类型作为泛型参数?

Angular @Watch装饰器自动推导类与属性类型实现方案

完全可以实现无需手动传递泛型参数的自动类型推导,利用TypeScript的装饰器类型推断机制和类型工具就能达成目标。以下是具体实现方案:

核心实现思路

  1. 调整装饰器的泛型定义,将泛型参数绑定到属性装饰器的目标类原型和属性名上,让TypeScript自动从这两个值推断出类类型和属性类型
  2. 修正回调函数的类型约束,确保this自动指向当前类实例,last/current自动匹配被装饰属性的类型
  3. 保留原有的深度监听逻辑,仅优化类型推导部分

修改后的@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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 15:32:41