How to fix Decorators are not valid here in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 8, 2025· 143 views

This TypeScript error occurs when you try to use decorators in unsupported contexts like class expressions, anonymous classes, or ambient declarations. The fix involves restructuring your code to use decorators only on named class declarations, methods, properties, accessors, or parameters.

Quick fix

Fixes TS1206

// WRONG - Decorator in instantiated class expression
export default new class {
  @someDecorator
  someMethod() {
    return "hello";
  }
}

// CORRECT - Define class separately, then instantiate
class MyClass {
  @someDecorator
  someMethod() {
    return "hello";
  }
}

export default new MyClass();
  1. Convert class expressions to named class declarations
  2. Remove decorators from ambient declarations
  3. Move decorators from overload signatures to implementation
  4. Enable decorator support in tsconfig.json
typescript — error
// WRONG - Decorator in instantiated class expression
export default new class {
@someDecorator
someMethod() {
return "hello";
}
}
// CORRECT - Define class separately, then instantiate
class MyClass {
@someDecorator
someMethod() {
return "hello";
}
}
export default new MyClass();
Decorators are not valid here

What this error means

TypeScript decorators are a special syntax that allows you to annotate and modify classes and their members. However, decorators can only be used in specific syntactic contexts. When you try to apply a decorator in an unsupported location, TypeScript emits error TS1206: "Decorators are not valid here." This error typically occurs in several situations: 1. **Class expressions**: When you use decorators on methods or properties inside a class that's defined as an expression (like returning an anonymous class from a function or instantiating a class inline) 2. **Ambient declarations**: When you try to use decorators in .d.ts declaration files or in 'declare' blocks 3. **Overload signatures**: When decorators are applied to function/method overload signatures rather than the implementation Decorators are only valid on: - Named class declarations (not expressions) - Class methods (in named classes) - Class properties (in named classes) - Class accessors (get/set) (in named classes) - Method/constructor parameters (in named classes) The restriction exists because decorators need to attach metadata to a stable, named construct that exists at runtime. Anonymous classes and ambient declarations don't meet these requirements.

Typical symptoms

  • TypeScript compilation fails with error code TS1206
  • Error message: 'Decorators are not valid here' pointing to a decorator
  • Decorators work in some parts of your code but fail in others
  • Error appears in class expressions returned from factory functions
  • Error occurs in .d.ts declaration files or 'declare' blocks
  • Angular or NestJS components fail to compile when using certain class patterns
  • Decorators on method overload signatures trigger the error

Common causes

  1. Using decorators on methods/properties inside a class expression (e.g., export default new class {})
  2. Applying decorators inside an anonymous class returned from a function
  3. Using decorators in .d.ts declaration files or ambient contexts (declare class)
  4. Placing decorators on function overload signatures instead of the implementation
  5. Using decorators on class members in immediately-instantiated classes
  6. Attempting to use parameter decorators in declaration files or overload signatures
  7. Applying accessor decorators to both get and set of the same property
  8. Using decorators on non-exported class expressions in modules

How to fix "Decorators are not valid here"

1Convert class expressions to named class declarations

If you're using decorators inside a class expression, convert it to a named class declaration first:

typescript
// WRONG - Decorator in instantiated class expression
export default new class {
  @someDecorator
  someMethod() {
    return "hello";
  }
}

// CORRECT - Define class separately, then instantiate
class MyClass {
  @someDecorator
  someMethod() {
    return "hello";
  }
}

export default new MyClass();

For factory functions returning classes with decorators:

typescript
// WRONG - Anonymous class with decorators
function createMixin() {
  return class {
    @log
    doSomething() {}
  };
}

// CORRECT - Named class declaration
function createMixin() {
  class Mixin {
    @log
    doSomething() {}
  }
  return Mixin;
}
2Remove decorators from ambient declarations

Decorators cannot be used in .d.ts files or 'declare' blocks. Remove them from type declarations:

typescript
// WRONG - Decorators in declaration file (.d.ts)
declare class MyService {
  @inject(HttpClient)
  constructor(http: HttpClient);

  @cache()
  getData(): Promise<Data>;
}

// CORRECT - Plain type declarations only
declare class MyService {
  constructor(http: HttpClient);
  getData(): Promise<Data>;
}

If you need decorator metadata for third-party libraries, put the actual implementation in a .ts file:

typescript
// my-service.ts - Implementation with decorators
import { inject, cache } from 'my-framework';

export class MyService {
  @inject(HttpClient)
  constructor(http: HttpClient) {}

  @cache()
  getData(): Promise<Data> {
    // implementation
  }
}
3Move decorators from overload signatures to implementation

Decorators should be placed on the implementation signature, not on overload signatures:

typescript
// WRONG - Decorator on overload signature
class Calculator {
  @validate
  add(a: number, b: number): number;
  @validate
  add(a: string, b: string): string;
  add(a: any, b: any): any {
    return a + b;
  }
}

// CORRECT - Decorator on implementation only
class Calculator {
  add(a: number, b: number): number;
  add(a: string, b: string): string;
  @validate
  add(a: any, b: any): any {
    return a + b;
  }
}

For parameter decorators on overloads:

typescript
// WRONG - Parameter decorator on overload
class Service {
  process(@validate data: string): void;
  process(@validate data: number): void;
  process(data: any): void {
    // implementation
  }
}

// CORRECT - Parameter decorator on implementation
class Service {
  process(data: string): void;
  process(data: number): void;
  process(@validate data: any): void {
    // implementation
  }
}
4Enable decorator support in tsconfig.json

Ensure your tsconfig.json has decorator support enabled:

For legacy decorators (most frameworks still use this):

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

For TypeScript 5.0+ native decorators (no flag needed):

json
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022"]
  }
}

Note: Most frameworks (Angular, NestJS, TypeORM) still require experimentalDecorators: true. Native decorators in TS 5.0+ are a different, incompatible implementation.

5Refactor Angular/NestJS patterns correctly

In Angular and NestJS, decorators must be on properly exported classes:

typescript
// WRONG - Decorator placement in module
export const routes = [
  { path: '/', component: HomeComponent }
];

@NgModule({
  declarations: [AppComponent],
  imports: [RouterModule.forRoot(routes)]
})
export class AppModule {}

// CORRECT - Routes defined before decorator
const routes = [
  { path: '/', component: HomeComponent }
];

@NgModule({
  declarations: [AppComponent],
  imports: [RouterModule.forRoot(routes)]
})
export class AppModule {}

For NestJS controllers:

typescript
// WRONG - Anonymous controller class
export const UserController = new class {
  @Get()
  getUsers() {
    return [];
  }
}

// CORRECT - Named exported class
@Controller('users')
export class UserController {
  @Get()
  getUsers() {
    return [];
  }
}
6Fix accessor decorator placement

TypeScript only allows decorators on the first accessor (get or set) of a property:

typescript
// WRONG - Decorators on both get and set
class User {
  private _name: string = '';

  @log
  get name() {
    return this._name;
  }

  @log  // Error: Decorators are not valid here
  set name(value: string) {
    this._name = value;
  }
}

// CORRECT - Decorator on first accessor only (typically the getter)
class User {
  private _name: string = '';

  @log
  get name() {
    return this._name;
  }

  set name(value: string) {
    this._name = value;
  }
}

The decorator applies to the property descriptor as a whole, so you only need it once.

Advanced notes

### TypeScript 5.0+ Decorator Changes

TypeScript 5.0 introduced a new decorator implementation aligned with the TC39 ECMAScript proposal. These new decorators:

- Don't require the experimentalDecorators flag
- Use a different signature (receive a context object)
- Are NOT compatible with existing decorator libraries

Example of new-style decorator:

typescript
// TypeScript 5.0+ decorator
function logged<T>(
  value: Function,
  context: ClassMethodDecoratorContext<T>
) {
  const methodName = String(context.name);

  return function (this: T, ...args: any[]) {
    console.log(`Calling ${methodName}`);
    return value.call(this, ...args);
  };
}

class Calculator {
  @logged
  add(a: number, b: number) {
    return a + b;
  }
}

Most frameworks (Angular, NestJS, TypeORM, etc.) still require experimentalDecorators: true and won't work with TS 5.0+ decorators.

### Class Expression vs Class Declaration

Understanding the difference helps avoid decorator errors:

typescript
// Class DECLARATION (decorators allowed)
class MyClass {
  @decorator
  method() {}
}

// Class EXPRESSION (decorators NOT allowed on members)
const MyClass = class {
  @decorator  // TS1206 error
  method() {}
};

// IIFE class expression (decorators NOT allowed)
export default new class {
  @decorator  // TS1206 error
  method() {}
}

### Decorator Evaluation Order

When multiple decorators are used, they're evaluated in a specific order:

typescript
@classDecorator
class Example {
  @propertyDecorator
  prop: string = "test";

  @methodDecorator
  method(@paramDecorator param: string) {}
}

// Evaluation order:
// 1. Property decorators (top to bottom)
// 2. Parameter decorators (left to right)
// 3. Method decorators (top to bottom)
// 4. Class decorators (last)

### Mixin Pattern with Decorators

If you need decorators in mixin classes:

typescript
// Define mixin as named class
class LoggingMixin {
  @log
  logMessage(msg: string) {
    console.log(msg);
  }
}

// Apply mixin to target class
function applyMixins(targetClass: any, mixins: any[]) {
  mixins.forEach(mixin => {
    Object.getOwnPropertyNames(mixin.prototype).forEach(name => {
      targetClass.prototype[name] = mixin.prototype[name];
    });
  });
}

class MyClass {}
applyMixins(MyClass, [LoggingMixin]);

Frequently asked questions

What does "TS1206" mean?
TypeScript decorators are a special syntax that allows you to annotate and modify classes and their members. However, decorators can only be used in specific syntactic contexts. " This error typically occurs in several situations: 1.
How do I fix "TS1206"?
This TypeScript error occurs when you try to use decorators in unsupported contexts like class expressions, anonymous classes, or ambient declarations. The fix involves restructuring your code to use decorators only on named class declarations, methods, properties, accessors, or parameters.
What causes "TS1206"?
Using decorators on methods/properties inside a class expression (e.g., export default new class {}) Applying decorators inside an anonymous class returned from a function Using decorators in .d.ts declaration files or ambient contexts (declare class)
Is the "TS1206" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading