How to fix Decorator cannot be applied to this kind of declaration in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 8, 2025· 123 views

This error occurs when you try to apply a TypeScript decorator to a language construct that doesn't support decorators. Decorators can only be applied to classes, methods, accessors, properties, and parameters—not to standalone functions, interfaces, type aliases, or variables.

Quick fix

Fixes Decorator cannot be applied to this kind of declaration

// WRONG - decorators don't work on standalone functions
@Log
function calculateTotal(price: number): number {
  return price * 1.1;
}
// Error: Decorator cannot be applied to this kind of declaration

// CORRECT - use a class method instead
class Calculator {
  @Log
  calculateTotal(price: number): number {
    return price * 1.1;
  }
}
  1. Convert standalone functions to class methods
  2. Remove decorators from interfaces and type aliases
  3. Use property decorators instead of decorating variables
  4. Fix parameter decorators on class methods
typescript — error
// WRONG - decorators don't work on standalone functions
@Log
function calculateTotal(price: number): number {
return price * 1.1;
}
// Error: Decorator cannot be applied to this kind of declaration
// CORRECT - use a class method instead
class Calculator {
@Log
calculateTotal(price: number): number {
return price * 1.1;
}
}
Decorator cannot be applied to this kind of declaration

What this error means

The "Decorator cannot be applied to this kind of declaration" error appears when you attempt to use a decorator on an unsupported construct. TypeScript decorators are special declarations that can modify or observe classes and class members, but they have strict limitations about where they can be used. TypeScript supports five types of decorators, each with specific rules: 1. **Class decorators** - Applied to class declarations 2. **Method decorators** - Applied to class methods 3. **Accessor decorators** - Applied to getters/setters 4. **Property decorators** - Applied to class properties 5. **Parameter decorators** - Applied to method or constructor parameters You cannot apply decorators to standalone functions, arrow functions, interfaces, type aliases, variable declarations, function parameters (outside of class contexts), or exported namespace members. Additionally, decorators cannot be used in ambient contexts like declaration files (.d.ts) or declare blocks. The most common mistake is attempting to decorate a standalone function instead of a class method, or trying to use decorators on constructs that only exist at compile-time (like interfaces and type aliases).

Typical symptoms

  • Compilation fails with 'Decorator cannot be applied to this kind of declaration'
  • Decorators on standalone functions trigger errors
  • Attempting to decorate interfaces or type aliases fails
  • Decorators on arrow functions are rejected by the compiler
  • Trying to use parameter decorators on standalone functions causes errors
  • Decorators in .d.ts declaration files produce compilation errors

Common causes

  1. Attempting to decorate a standalone function instead of a class method
  2. Trying to apply decorators to interfaces or type aliases
  3. Using decorators on arrow function expressions
  4. Applying decorators to variable declarations or constants
  5. Attempting to use parameter decorators on non-class function parameters
  6. Decorating exported namespace members inappropriately
  7. Using decorators in ambient contexts (declaration files or declare blocks)
  8. Applying method decorators to function overload signatures instead of the implementation

How to fix "Decorator cannot be applied to this kind of declaration"

1Convert standalone functions to class methods

If you're trying to decorate a standalone function, convert it to a class method:

typescript
// WRONG - decorators don't work on standalone functions
@Log
function calculateTotal(price: number): number {
  return price * 1.1;
}
// Error: Decorator cannot be applied to this kind of declaration

// CORRECT - use a class method instead
class Calculator {
  @Log
  calculateTotal(price: number): number {
    return price * 1.1;
  }
}

For utility functions, create a utility class:

typescript
class MathUtils {
  @Measure
  static calculatePercentage(value: number, total: number): number {
    return (value / total) * 100;
  }
}

// Usage
const result = MathUtils.calculatePercentage(45, 200);

This pattern works for both instance and static methods.

2Remove decorators from interfaces and type aliases

Decorators only work on runtime constructs, not compile-time only types:

typescript
// WRONG - interfaces are compile-time only
@Serializable
interface User {
  name: string;
  email: string;
}
// Error: Decorator cannot be applied to this kind of declaration

// CORRECT - use a class instead
@Serializable
class User {
  name: string;
  email: string;

  constructor(name: string, email: string) {
    this.name = name;
    this.email = email;
  }
}

If you need both a type and runtime behavior:

typescript
// Define interface for type checking
interface IUser {
  name: string;
  email: string;
}

// Implement with decoratable class
@Serializable
class User implements IUser {
  constructor(
    public name: string,
    public email: string
  ) {}
}
3Use property decorators instead of decorating variables

Variable declarations cannot be decorated. Use class properties instead:

typescript
// WRONG - can't decorate variables
@Observable
const counter = 0;
// Error: Decorator cannot be applied to this kind of declaration

// CORRECT - use class property
class AppState {
  @Observable
  counter = 0;

  @Observable
  private userName = "";
}

For reactive state management patterns:

typescript
class Store {
  @Track
  private items: string[] = [];

  @Computed
  get itemCount(): number {
    return this.items.length;
  }

  @Action
  addItem(item: string): void {
    this.items.push(item);
  }
}
4Fix parameter decorators on class methods

Parameter decorators only work on class method and constructor parameters, not standalone functions:

typescript
// WRONG - standalone function parameter
function greet(@Validate name: string) {
  console.log(`Hello, ${name}`);
}
// Error: Decorator cannot be applied to this kind of declaration

// CORRECT - class method parameter
class Greeter {
  greet(@Validate name: string) {
    console.log(`Hello, ${name}`);
  }
}

For constructor parameters:

typescript
class UserService {
  constructor(
    @Inject('Database') private db: Database,
    @Inject('Logger') private logger: Logger
  ) {}

  async findUser(@ValidateId userId: string) {
    return this.db.query('users', userId);
  }
}

Note: Standard decorators (TypeScript 5.0+ without experimentalDecorators) don't support parameter decorators at all.

5Check decorator compatibility with TypeScript version

TypeScript 5.0 introduced standard decorators that have different rules than experimental decorators:

json
// tsconfig.json - Using experimental decorators (legacy)
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Standard decorators (TypeScript 5.0+) without the flag:
- Don't support parameter decorators
- Don't support decorating function overloads
- Don't work with emitDecoratorMetadata

If you're using frameworks like Angular, NestJS, or TypeORM that require experimental decorators:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

If using standard decorators:

typescript
// Use 'accessor' keyword for auto-accessors
class Example {
  @tracked accessor count = 0;  // Standard decorator syntax
}
6Avoid decorators in declaration files and ambient contexts

Decorators cannot be used in .d.ts files or ambient (declare) contexts:

typescript
// WRONG - in a .d.ts file
declare class User {
  @Validate
  name: string;
}
// Error: Decorator cannot be applied to this kind of declaration

// CORRECT - remove decorators from declaration files
declare class User {
  name: string;
}

If you need both type declarations and runtime decorators:

typescript
// types.d.ts - declarations only
declare class User {
  name: string;
  validate(): boolean;
}

// user.ts - implementation with decorators
export class User {
  @Length(3, 50)
  name: string;

  @Validate
  validate(): boolean {
    // implementation
    return true;
  }
}

Don't use decorators in declare module or declare global blocks either.

Advanced notes

### Experimental vs Standard Decorators

TypeScript has two decorator implementations with different restrictions:

Experimental Decorators (pre-TypeScript 5.0, requires experimentalDecorators: true):
- Support all five decorator types including parameter decorators
- Work with emitDecoratorMetadata for reflection
- Used by Angular, NestJS, TypeORM, InversifyJS
- Based on the Stage 2 TC39 proposal

Standard Decorators (TypeScript 5.0+, default without the flag):
- Don't support parameter decorators
- Don't support emitDecoratorMetadata
- Can't change the kind of class member (method stays method, accessor stays accessor)
- Introduce accessor keyword for auto-accessors
- Based on the Stage 3 TC39 proposal

If you get decorator errors after upgrading to TypeScript 5.0+, check if you're using legacy decorators:

bash
# Search for parameter decorators in your codebase
grep -r "@.*(" src/ | grep "parameter"

### Decorator Execution Order

When multiple decorators are applied to class members, they execute in a specific order:

1. Instance members: Parameter decorators → Accessor/Property/Method decorators
2. Static members: Parameter decorators → Accessor/Property/Method decorators
3. Constructor: Parameter decorators
4. Class: Class decorator

Example:

typescript
@ClassDecorator
class Example {
  @PropertyDecorator
  prop = 1;

  @MethodDecorator
  method(@ParamDecorator arg: string) {}

  constructor(@ParamDecorator param: number) {}
}

// Execution order:
// 1. @ParamDecorator (on method parameter)
// 2. @MethodDecorator
// 3. @PropertyDecorator
// 4. @ParamDecorator (on constructor parameter)
// 5. @ClassDecorator

### Workarounds for Standalone Functions

If you absolutely need decorator-like behavior on standalone functions, use higher-order functions:

typescript
// Decorator-style wrapper for standalone functions
function measurePerformance<T extends (...args: any[]) => any>(
  fn: T
): T {
  return ((...args: any[]) => {
    const start = performance.now();
    const result = fn(...args);
    const end = performance.now();
    console.log(`Execution time: ${end - start}ms`);
    return result;
  }) as T;
}

// Usage
const calculateTotal = measurePerformance((price: number) => {
  return price * 1.1;
});

This gives decorator-like functionality without requiring class methods.

### Framework-Specific Considerations

Angular - Requires experimental decorators:

typescript
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: '<h1>Hello</h1>'
})
export class AppComponent {}

NestJS - Heavily uses parameter decorators:

typescript
@Controller('users')
export class UsersController {
  @Get(':id')
  findOne(@Param('id') id: string) {
    return `User #${id}`;
  }
}

TypeORM - Entity decorators require experimental mode:

typescript
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;
}

All these frameworks require experimentalDecorators: true in tsconfig.json.

### Debugging Decorator Issues

Enable verbose compiler output to see decorator evaluation:

bash
npx tsc --showConfig | grep -i decorator
npx tsc --listFiles | grep decorator

Check which decorators are being evaluated:

typescript
function DebugDecorator(target: any, propertyKey?: string, descriptor?: PropertyDescriptor) {
  console.log('Decorator applied to:', target, propertyKey, descriptor);
}

Frequently asked questions

What does "Decorator cannot be applied to this kind of declaration" mean?
The "Decorator cannot be applied to this kind of declaration" error appears when you attempt to use a decorator on an unsupported construct. TypeScript decorators are special declarations that can modify or observe classes and class members, but they have strict limitations about where they can be used. TypeScript supports five types of decorators, each with specific rules: 1.
How do I fix "Decorator cannot be applied to this kind of declaration"?
This error occurs when you try to apply a TypeScript decorator to a language construct that doesn't support decorators. Decorators can only be applied to classes, methods, accessors, properties, and parameters—not to standalone functions, interfaces, type aliases, or variables.
What causes "Decorator cannot be applied to this kind of declaration"?
Attempting to decorate a standalone function instead of a class method Trying to apply decorators to interfaces or type aliases Using decorators on arrow function expressions
Is the "Decorator cannot be applied to this kind of declaration" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading