Concept lesson

TypeScript Decorators & Metadata

Stage 3 TC39 decorators, legacy experimental decorators, and reflect-metadata reflection.

lesson
Freshness: current14 min read
Mastery
not started · 0%

Learning outcomes

  • Author Stage 3 class and method decorators
  • Leverage metadata reflection in frameworks

Mental model

Decorators are higher-order functions applied to classes, methods, accessors, and fields during class definition, wrapping target elements with meta-programming behaviors.

Class Definition Evaluation
Execute Decorator Factory
Attach Metadata to Reflect Target
Return Wrapped Class/Method
Conceptual teaching model synthesized from:TypeScript 5.4 Language Specification & Type System Mechanics

Theory

TypeScript 5.0 introduced native Stage 3 TC39 decorators which operate without experimentalDecorators. Stage 3 decorators receive context objects containing metadata registries (context.metadata). Frameworks like NestJS use metadata reflection to dynamically wire controllers, dependency injectors, and ORM entity mappings.

export function LogExecutionTime<This, Args extends any[], Return>(
  target: (this: This, ...args: Args) => Return,
  context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
) {
  const methodName = String(context.name);
  return function (this: This, ...args: Args): Return {
    const start = performance.now();
    const result = target.call(this, ...args);
    const elapsed = (performance.now() - start).toFixed(2);
    console.log(`[LOG]: Method '${methodName}' executed in ${elapsed}ms`);
    return result;
  };
}

export class OrderService {
  @LogExecutionTime
  processOrder(orderId: string): { status: string } {
    return { status: `Order ${orderId} processed` };
  }
}

Alternatives and trade-offs

  • Stage 3 Decorators (TS 5.0+): Standardized, clean type safety; does not require experimentalDecorators.
  • Legacy Experimental Decorators (TS 4.x): Required experimentalDecorators: true and emitDecoratorMetadata.

Failure modes and misconceptions

  1. Decorator execution timing: Decorators run once when the class is defined/imported, NOT when instances are instantiated.
  2. Context this binding: Arrow functions inside decorators can break explicit this receiver bindings.
Reflect before revealing the guide

Decision scenario

Use Stage 3 TC39 decorators with explicit ClassMethodDecoratorContext parameters for new TypeScript 5.x codebases to avoid legacy polyfill requirements.

Learning outcomes

  • Differentiate Stage 3 TC39 decorators from legacy experimental decorators.
  • Author type-safe class method decorators with execution context objects.
  • Integrate metadata reflection into enterprise framework architectures.

Trade-offs

Decorators provide clean declarative syntax for cross-cutting concerns (logging, auth, validation), but execute at module evaluation time rather than instance runtime.

Evidence assessment

Theory and decision mastery

not-started · 0%
theory0%
decision0%
activityNot mapped
projectNot mapped
1. When are class and method decorators executed in JavaScript/TypeScript?
2. What is the main advantage of Stage 3 ECMAScript decorators introduced in TypeScript 5.0?
3. What error occurs if legacy decorators using reflect-metadata are run without importing the polyfill?

Decision scenario

A team is building a microservices framework in TypeScript 5.4 that decorates handler methods to measure latency.

Which decorator design pattern provides modern type safety without legacy polyfills?

Primary sources