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

TypeScript类装饰器未按预期工作,报'id不存在于User类型'错误

TypeScript装饰器报错:Property 'id' does not exist on type 'User' 的原因与解决

问题根源

TypeScript的类型检查系统不会自动识别装饰器给类原型动态添加的属性——哪怕你已经启用了experimentalDecorators配置。装饰器是在运行时给类原型挂载属性,但编译阶段TypeScript只依据你编写的User类定义做检查,而原类里没声明id和created,所以会抛出类型错误。

三种解决办法

  • 显式声明属性类型
    在User类里提前把装饰器要添加的属性声明出来,用可选属性或明确类型均可:

    function BaseEntity(ctr: Function) {
        ctr.prototype.id = Math.random();
        ctr.prototype.created = new Date();
    }
    
    @BaseEntity
    class User {
      id?: number; // 显式声明id属性
      created?: Date; // 显式声明created属性
      constructor(public name: string) {}
    }
    
    let user = new User("Sarah");
    console.log(user.id);
    
  • 使用接口合并
    定义一个和类同名的接口,把装饰器新增的属性写入接口,TypeScript会自动合并类与接口的类型:

    function BaseEntity(ctr: Function) {
        ctr.prototype.id = Math.random();
        ctr.prototype.created = new Date();
    }
    
    interface User {
      id: number;
      created: Date;
    }
    
    @BaseEntity
    class User {
      constructor(public name: string) {}
    }
    
    let user = new User("Sarah");
    console.log(user.id);
    
  • 修改装饰器为返回子类的形式
    让装饰器返回一个继承原类的子类,把新增属性直接定义在子类中,TypeScript能完整识别类型:

    function BaseEntity<T extends new (...args: any[]) => {}>(ctr: T) {
      return class extends ctr {
        id = Math.random();
        created = new Date();
      }
    }
    
    @BaseEntity
    class User {
      constructor(public name: string) {}
    }
    
    let user = new User("Sarah");
    console.log(user.id);
    

内容的提问来源于stack exchange,提问作者Genesist

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:27:22