Decorators

A decorator is a function written as @name before a class or member. It receives the value and a context (kind, name, addInitializer()) and may return a replacement. The accessor keyword creates a getter/setter pair for decorators to intercept, as in Lit's @property.

Status (September 2026): TC39 moved decorators back from Stage 3 to Stage 2.7 in May 2026, and no browser or Node.js 2,131 release runs them natively. Use TypeScript 5.0+ (without the legacy experimentalDecorators) or @babel/plugin-proposal-decorators with version: "2023-11". Node 25 rejects the @, so the output below comes from npx tsc --target es2022 account.ts and node account.js.

Method decorators compiled with TypeScript (not runnable directly in Node)JavaScriptLive
function logged(method: any, context: ClassMethodDecoratorContext) {
  return function (this: any, ...args: any[]) {                // replaces the method
    console.log(`call ${String(context.name)}(${args})`);
    return method.apply(this, args);
  };
}
const bound = (_method: any, context: ClassMethodDecoratorContext) => context.addInitializer(
  function (this: any) { this[context.name] = this[context.name].bind(this); });  // per instance
class Account {
  balance = 10;
  @bound @logged deposit(amount: number) { return (this.balance += amount); }
}
const { deposit } = new Account();                             // detached, still bound
console.log(deposit(5));

Decorators apply right to left: @logged wraps first, then @bound binds the wrapper (see also Reference Topics).