- TypeScript Tutorial
- TypeScript Home
- TypeScript Introduction
- TypeScript Setup
- TypeScript First Program
- TypeScript vs JavaScript
- TypeScript Data Types
- TypeScript Type Inference
- TypeScript Type Annotations
- TypeScript Interfaces
- TypeScript Enums
- TypeScript Type Aliases
- TypeScript Type Assertions
- TypeScript Variables
- TypeScript Functions
- TypeScript Functions
- TypeScript Optional Parameters
- TypeScript Default Parameters
- TypeScript Rest Parameters
- TypeScript Arrow Functions
- Classes and Objects
- Introduction to Classes
- Properties and Methods
- Access Modifiers
- Static Members
- Inheritance
- Abstract Classes
- Interfaces vs Classes
- Advanced Types
- TypeScript Union Types
- TypeScript Intersection Types
- TypeScript Literal Types
- TypeScript Nullable Types
- TypeScript Type Guards
- TypeScript Discriminated Unions
- TypeScript Index Signatures
- TypeScript Generics
- Introduction to Generics
- TypeScript Generic Functions
- TypeScript Generic Classes
- TypeScript Generic Constraints
- TypeScript Modules
- Introduction to Modules
- TypeScript Import and Export
- TypeScript Default Exports
- TypeScript Namespace
- Decorators
- Introduction to Decorators
- TypeScript Class Decorators
- TypeScript Method Decorators
- TypeScript Property Decorators
- TypeScript Parameter Decorators
- Configuration
- TypeScript tsconfig.json File
- TypeScript Compiler Options
- TypeScript Strict Mode
- TypeScript Watch Mode
TypeScript Class Decorators
Class decorators in TypeScript are a special kind of decorator that can be applied to a class declaration. They are used to modify or extend the behavior of the class at design time. A class decorator is a function that is applied to the constructor of the class.
Class decorators are often used in frameworks like Angular to add functionality such as dependency injection or logging, without modifying the original class directly.
What is a Class Decorator?
A class decorator is a function that takes the target class constructor as an argument. It can modify the class's prototype, add properties or methods, or even replace the class with another class.
Class decorators are prefixed with the @ symbol, followed by the decorator name, and are applied to the class itself.
Enabling Class Decorators in TypeScript
Before using decorators in TypeScript, you must enable the experimentalDecorators option in the tsconfig.json file.
Example: Enabling Class Decorators
{
"compilerOptions": {
"experimentalDecorators": true
}
}
- The
experimentalDecoratorsoption allows the use of decorators, which are not yet fully standardized in JavaScript.
Syntax of Class Decorators
A class decorator is a function that takes the target class constructor as an argument.
function MyClassDecorator(constructor: Function) {
console.log("Class decorated:", constructor);
}
Here, MyClassDecorator is a decorator function that logs the class constructor to the console. The decorator will be applied to the class when it is instantiated.
Applying Class Decorators
To apply a class decorator, simply place the decorator before the class declaration.
Example: Applying a Class Decorator
function LogClass(target: Function) {
console.log(`Class ${target.name} has been decorated.`);
}
@LogClass
class Person {
constructor(public name: string, public age: number) {}
}
const person = new Person('John', 25);
// Output: Class Person has been decorated.
- The
LogClassdecorator is applied to thePersonclass. When an instance ofPersonis created, the decorator logs a message to the console indicating that the class has been decorated.
Modifying the Class Behavior
Class decorators can modify the class by adding new methods, properties, or modifying its constructor. Decorators can even replace the class constructor with a new one.
Example: Modifying the Class Constructor
function AddMethod(target: Function) {
target.prototype.sayHello = function() {
console.log("Hello from the decorator!");
};
}
@AddMethod
class Person {
constructor(public name: string, public age: number) {}
}
const person = new Person('John', 25);
person.sayHello(); // Output: Hello from the decorator!
- In this example, the
AddMethoddecorator adds a new methodsayHelloto the class prototype, making it available on all instances of thePersonclass.
Replacing the Class Constructor
A class decorator can also replace the class constructor with a new one. This can be useful if you want to modify the instantiation logic of a class.
Example: Replacing the Constructor
function ReplaceConstructor(target: Function) {
const newConstructor = function(this: any) {
console.log("New constructor called.");
this.name = "Default Name";
this.age = 30;
};
newConstructor.prototype = target.prototype;
return newConstructor;
}
@ReplaceConstructor
class Person {
constructor(public name: string, public age: number) {}
}
const person = new Person('John', 25);
console.log(person.name); // Output: Default Name
console.log(person.age); // Output: 30
- Here, the
ReplaceConstructordecorator replaces thePersonclass constructor with a new one that assigns default values tonameandage. Even though thePersonclass is instantiated with arguments, the new constructor is called.
Class Decorator with Parameters
You can also pass parameters to class decorators by using a decorator factory. A decorator factory is a function that returns a decorator function.
Example: Class Decorator with Parameters
function Logger(message: string) {
return function(target: Function) {
console.log(`${message} - Class ${target.name}`);
};
}
@Logger("Logging")
class Person {
constructor(public name: string, public age: number) {}
}
const person = new Person('John', 25);
// Output: Logging - Class Person
- In this example, the
Loggerdecorator factory allows you to pass amessageparameter to customize the log message.
Using Class Decorators for Dependency Injection (DI)
In frameworks like Angular, class decorators are used for dependency injection. The @Injectable() decorator, for example, marks a class as available for DI, and the framework automatically resolves and injects the dependencies when the class is instantiated.
Example: Dependency Injection with Class Decorators (Simulated)
function Injectable(target: Function) {
// Simulating dependency injection by storing the class in a registry
const container = (window as any).container || (window as any).container = {};
container[target.name] = target;
}
@Injectable
class Service {
constructor(public name: string) {}
}
const service = new (window as any).container.Service("My Service");
console.log(service.name); // Output: My Service
- The
@Injectabledecorator marks theServiceclass as injectable, and we simulate a simple DI container to resolve and instantiate the class with its dependencies.
Summary
- Class decorators in TypeScript are used to modify or extend the behavior of a class.
- They are prefixed with
@and can modify the class prototype, add methods, or even replace the class constructor. - Decorators are enabled by setting
experimentalDecorators: truein thetsconfig.jsonfile. - Class decorators can be used to add functionality like logging, dependency injection, or even modify the class structure.