Angular NG2007 Error: Fixing "Class is using Angular features but is not decorated"
Problem Statement
When creating a base class that contains Angular-specific features like @Input() decorators and extending this class in your Angular components, you may encounter the following error:
ERROR: Class is using Angular features but is not decorated. Please add an explicit Angular decorator.This occurs when:
- You have a base class with Angular decorators like
@Input(),@Output(), or@ViewChild() - Your derived components extend this base class
- The base class itself lacks an Angular decorator
Solution: Adding an Appropriate Decorator
For Angular 10+ (Recommended)
Use the @Directive() decorator for your base class:
import { Directive, Input } from '@angular/core';
@Directive()
export abstract class BaseComponent {
@Input() teamName: string;
@Input() teamSize: number;
@Input() players: any;
}This approach:
- Doesn't require dependency injection compatibility
- Clearly indicates the class serves as a base for components/directives
- Follows Angular's official migration guidance
For Component-Specific Base Classes
If your base class needs component-specific functionality, use @Component():
import { Component, Input } from '@angular/core';
@Component({
template: ''
})
export abstract class BaseComponent {
@Input() teamName: string;
@Input() teamSize: number;
@Input() players: any;
}WARNING
Using @Component() requires that all constructor arguments be resolvable through Angular's dependency injection system.
Alternative: Using @Injectable()
You can also use @Injectable() as an alternative:
import { Injectable, Input } from '@angular/core';
@Injectable()
export abstract class BaseComponent {
@Input() teamName: string;
@Input() teamSize: number;
@Input() players: any;
}Implementation Example
Here's how to properly structure your components:
Base Component
import { Directive, Input } from '@angular/core';
@Directive()
export abstract class BaseComponent {
@Input() teamName: string;
@Input() teamSize: number;
@Input() players: any[];
// Common methods can be defined here
getPlayerCount(): number {
return this.players?.length || 0;
}
}Derived Component
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-cricket',
templateUrl: './cricket.component.html',
styleUrls: ['./cricket.component.scss']
})
export class CricketComponent extends BaseComponent implements OnInit {
constructor() {
super();
}
ngOnInit(): void {
// Component-specific initialization
}
// Component-specific methods
}Additional Considerations
TypeScript Version Compatibility
If you're using Angular 15+, ensure you're using a compatible TypeScript version:
npm install typescript@4.8.2 --save-dev --save-exactCode Organization
Ensure your class definitions are properly positioned in your files:
// Correct: Base class defined before component
export class HelperClass {
// Helper implementation
}
@Component({
selector: 'app-example',
template: '<div>Example</div>'
})
export class ExampleComponent {
// Component implementation
}
// Also acceptable: Base class defined after componentINFO
This error was introduced in Angular 10 as part of the Ivy compiler's stricter checking for undecorated base classes that use Angular features.
Best Practices
- Always mark base classes as
abstractto prevent direct instantiation - Use
@Directive()instead of@Component()when no template is needed - Keep base classes focused on common functionality only
- Follow Angular's migration guide for undecorated classes
By properly decorating your base classes, you'll resolve the NG2007 error while maintaining a clean, maintainable component architecture.