liveBook · Manning

Decorator

As explained in Essential TypeScript 5, Third Edition

A decorator function is a function invoked when a decorator is applied and returns the replacement class feature.

A decorator transforms a class or one of its features without changing the feature’s implementation directly. Apply one with `@` before a class, method, field, accessor, or auto-accessor. The decorator function receives the original feature and a context object, then supplies a replacement. section 14.2 section 14.8

Listing 14.13 Using decorator context in the methodDecorator.ts file in the src folder
export function time(method: any, ctx: ClassMethodDecoratorContext) {
   const methodName = String(ctx.name);
   return function(this: any, ...args: any[]) {
       const start = performance.now();
       console.log(`${methodName} started`);
       const result = method.call(this, ...args);
       const duration = (performance.now() - start).toFixed(2);
       console.log(`${methodName} ended ${duration} ms`);
       return result;
   }
}

In `src/methodDecorator.ts`, `time` receives the original method and `ClassMethodDecoratorContext`. Its replacement preserves `this` and the arguments, calls the original method, logs the elapsed time, and returns the result. Importing it and placing `@time` above a method applies that behavior without editing the method body. section 14.2.1 section 14.2

Choose the decorator form to match the transformation:

  • A class decorator can return a subclass with additional behavior. An added method works at runtime but does not automatically become part of the decorated class’s TypeScript type; an interface and type guard can provide type-safe access. section 14.3.1
  • A method decorator can use generic types to preserve or restrict the original method’s signature. An incompatible replacement or a class that fails a generic constraint produces a compiler error. section 14.2 section 14.2.2
  • A factory accepts settings before returning the decorator function. Apply it with parentheses, such as `@time()` or `@time("Product.getDetails")`; a configuration object can control labels, timing, or replacement behavior. section 14.4
  • When decorators are stacked, factory expressions are evaluated in written order, but replacement functions are built from the decorator closest to the feature outward. A shared `Map` can accumulate timing results across decorated methods. section 14.5 section 14.7

Angular configuration

`@NgModule({...})` describes related application features, while `@Component({...})` associates a component class with a selector and HTML template. Angular uses TypeScript’s earlier decorator implementation rather than the newer standard form, so its compiler configuration needs additional settings. section 18.2 section 18.6

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Works through method replacements, context data, generic constraints, class type limitations, factories, stacking order, and shared state.
Examples
Uses a timed method, a serializing subclass, stacked message decorators, accumulated timing data, and Angular module and component declarations.
What it assumes
Assumes familiarity with TypeScript classes and functions while introducing decorator syntax and the distinction between decorator and replacement functions.
What you can do after
Build it from scratch to wrap methods, configure each application, and recognize a class decorator’s TypeScript type limitation.
How it connects
Connects decorators to classes, methods, generic types, type guards, factory functions, and Angular components.

Also explained in

Compare how 7 books explain decorator →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.