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

TypeScript中TypedPropertyDecorator泛型异常行为及修复方案

问题原因

TypeScript 对变量赋值和装饰器参数的类型安全校验逻辑存在差异:

  • 变量赋值场景:const test: Test = method 是安全的——Test 类型允许返回 Promise<void | Message>,而 method 返回更具体的 Promise<Message>(属于前者的子类型),符合协变规则,因此不会报错。
  • 装饰器场景:装饰器接收 TypedPropertyDescriptor<Test> 意味着它可能会替换原方法为一个返回 Promise<void | Message> 的函数(比如返回 void)。但类方法被定义为返回 Promise<Message>,调用者会期望得到 Message 类型值,若装饰器替换后返回 void 就会破坏类型安全。因此 TypeScript 禁止这种潜在不安全的赋值,触发类型错误。
修复方法

推荐使用泛型装饰器,既保留类型安全,又允许方法返回更具体的类型:

type Message = { Body: string };
type Test = (message: Message) => Promise<void | Message>;

// 此处无类型错误
const test: Test = async (message: Message) => ({ Body: 'hey' });

// 泛型装饰器,约束方法类型兼容 Test
const a = <T extends Test>(target: object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => {
    const og = descriptor.value;
    console.log('Hey')
};

class A {
    @a // 不再报错
    public async method(message: Message): Promise<Message> {
        return message;
    }
}

其他可选方案:

  • 放宽类方法的返回类型为 Promise<void | Message>,与 Test 类型完全匹配;
  • 直接将装饰器的参数类型改为 TypedPropertyDescriptor<(message: Message) => Promise<Message>>,但会限制装饰器只能用于返回 Message 的方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 16:06:28