欢迎光临
我们一直在努力

彻底告别 experimental:TypeScript 5.9 标准装饰器实战指南

📝 引言

📌 场景/痛点

在 TypeScript 5.0 之前,使用装饰器(Decorator)需要开启 experimentalDecorators 实验性选项。这种旧语法不仅与最终 ECMAScript 标准不一致,而且存在运行时开销大、类型元数据支持混乱等问题。

很多新手在面对 target、propertyKey、descriptor 这三件套时,往往是一知半解,甚至只是照搬网上的代码。

在 2026 年,装饰器已经定稿(Stage 4/Finalized)。 我们是时候拥抱新的标准写法,利用 context 对象和 addInitializer 来编写更优雅的元编程代码了。

✨ 最终效果

掌握新标准装饰器后,你将能写出像 Angular 或 NestJS 那样优雅的声明式代码。

在这里插入图片描述

📖 内容概览

本文将带你重构你的元编程思维:

  • 标准 vs 旧版:为什么我们要放弃 experimentalDecorators?
  • 核心新语法:value 与 context 的解构。
  • 实战演练:编写方法装饰器(日志)与字段装饰器(自动校验)。

  • 🛠️ 正文

    1. 环境准备

    在 TypeScript 5.9 中,使用标准装饰器无需开启 experimentalDecorators(实际上开启它反而会使用旧语法)。

    tsconfig.json 配置:

    {
    "compilerOptions": {
    "target": "ES2022",
    // ✅ 确保使用新标准
    "experimentalDecorators": false,
    }
    }

    2. 核心概念:新的函数签名

    旧版装饰器通常接收 3 个参数(target, key, descriptor),而新版标准装饰器只接收 2 个参数,且结构完全不同。

    2.1 方法装饰器

    新语法:(value, context) => { … }

    • value: 当前方法本身的函数。
    • context: 一个包含元数据的对象(kind, name, static, access, addInitializer)。
    2.2 类装饰器

    新语法:(value, context) => { … }

    • value: 当前类本身。

    3. 实战一:方法日志装饰器 (@Logged)

    我们要实现一个装饰器,给方法加上自动日志打印功能。

    // src/decorators/logged.ts

    // ✅ 新标准写法:只接受 value 和 context
    function Logged(value: Function, context: ClassMethodDecoratorContext) {
    // context.kind 告诉我们这是否是方法
    if (context.kind !== "method") return;

    // 替换原方法
    return function (this: any, args: any[]) {
    console.log(`[LOG] Calling method: ${String(context.name)}`);
    console.log(`[LOG] Arguments: ${JSON.stringify(args)}`);

    // 调用原方法
    const result = value.apply(this, args);

    console.log(`[LOG] Result: ${result}`);
    return result;
    };
    }

    // 使用
    class Calculator {
    @Logged
    add(a: number, b: number) {
    return a + b;
    }
    }

    const calc = new Calculator();
    calc.add(1, 2);
    // 输出:
    // [LOG] Calling method: add
    // [LOG] Arguments: [1, 2]
    // [LOG] Result: 3

    4. 实战二:字段自动校验装饰器 (@Positive)

    字段装饰器在标准版中有一个巨大的变化:它需要返回一个初始化函数。

    // src/decorators/positive.ts

    function Positive(value: undefined, context: ClassFieldDecoratorContext) {
    if (context.kind !== "field") return;

    // ✅ 返回一个函数,这个函数接收初始值
    return function (initialValue: number) {
    if (initialValue < 0) {
    throw new Error(`${String(context.name)} must be positive!`);
    }
    return initialValue;
    };
    }

    // 使用
    class Product {
    @Positive
    price: number = 99; // ✅ 正常

    @Positive
    discount: number = 10; // ❌ 报错:discount must be positive!
    }

    new Product()

    5. 实战三:初始化钩子 (addInitializer)

    这是标准装饰器的一大亮点。你可以添加一个初始化函数,该函数会在类实例化(构造函数执行前)或类定义时运行。

    function Init(value: undefined, context: ClassFieldDecoratorContext) {
    if (context.kind !== "field") return;

    // ✅ 添加初始化逻辑
    context.addInitializer(function() {
    // 这里的 this 是实例
    // 我们可以在对象创建前做些手脚,比如给对象加个属性
    (this as any).initialized = true;
    });
    }

    class User {
    @Init
    initialized!: boolean;
    }

    const u = new User();
    console.log(u.initialized); // true


    ❓ 常见问题

    Q1: 旧版装饰器还能用吗?

    A: 可以,但不推荐。只要开启 experimentalDecorators: true,旧代码依然能跑。但在 2026 年的新项目中,强烈建议使用标准装饰器,因为它运行时性能更好,且是 JS 官方标准。

    Q2: 新标准里 Reflect.getMetadata 还能用来获取参数类型吗?

    A: 这是一个痛点。标准的 ECMAScript 装饰器提案本身不包含类型元数据(Type Metadata)机制。 emitDecoratorMetadata 是 TS 的专有特性。目前(TS 5.9),要结合新装饰器使用类型注入(如 Angular/NestJS 的依赖注入),可能仍需一些变通或辅助库(如 reflect-metadata 的 Polyfill 或新的元数据提案)。纯业务开发(日志、校验)使用标准装饰器已完全足够。

    Q3: 装饰器 @sealed 怎么写?

    A: 对于类装饰器,你通常直接返回修改后的类,或者使用 addInitializer 封闭 prototype。

    function sealed(value: Function, context: ClassDecoratorContext) {
    Object.seal(value);
    Object.seal(value.prototype);
    }


    🎯 总结

    标准装饰器让 TypeScript 的元编程能力更加健壮和规范。本文我们掌握了:

  • 新签名:告别三参数,拥抱 (value, context)。
  • 字段装饰器:返回一个函数来处理初始化值。
  • 生命周期:利用 addInitializer 拦截实例化过程。
  • 🚀 下期预告: 掌握了前端和 Node.js 的 TS 开发,现在我们要挑战全栈。如何让后端的类型定义自动流向前端,彻底消除接口联调的烦恼? 下一篇文章我们将深入 《全栈类型共享:从 Prisma 到前端》,实现类型即真理。

    💬 互动环节: 你的项目里还在用旧版的 experimentalDecorators 吗?有没有尝试迁移到新标准? 如果觉得文章带你紧跟了技术前沿,请点赞👍、收藏⭐、关注👀,下期更精彩!

    赞(0)
    未经允许不得转载:171主机测评 » 彻底告别 experimental:TypeScript 5.9 标准装饰器实战指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址