Ответ
Нет, декораторы в TypeScript (и экспериментальные декораторы в JavaScript) могут применяться к нескольким типам объявлений. В моих Node.js проектах с TypeScript я использую декораторы для:
1. Декораторы классов — для регистрации в DI-контейнере, добавления метаданных:
import { Injectable, Singleton } from 'tsyringe';
@Injectable() // Декоратор класса
@Singleton() // Можно применять несколько декораторов
class DatabaseService {
constructor(private config: ConfigService) {}
async connect() {
return await mongoose.connect(this.config.databaseUrl);
}
}
2. Декораторы методов — для логирования, кэширования, валидации:
import { Get, Controller, UseGuards } from '@nestjs/common';
@Controller('users')
class UsersController {
@Get() // Декоратор метода HTTP
@UseGuards(AuthGuard) // Декоратор middleware
@CacheTTL(60) // Декоратор кэширования
async getAllUsers() {
return await this.userService.findAll();
}
}
3. Декораторы свойств — для валидации, сериализации, внедрения зависимостей:
import { Expose, Type } from 'class-transformer';
import { IsEmail, IsString } from 'class-validator';
class UserDto {
@Expose() // Декоратор свойства для class-transformer
id: number;
@IsString() // Валидация
@IsEmail() // Можно несколько декораторов
email: string;
@Type(() => Date) // Преобразование типа
createdAt: Date;
}
4. Декораторы параметров — для внедрения зависимостей в параметры конструктора/методов:
import { Inject } from '@nestjs/common';
class UserService {
constructor(
@Inject('USER_MODEL') // Декоратор параметра
private userModel: Model<User>,
@Inject(ConfigService)
private config: ConfigService
) {}
}
5. Декораторы аксессоров (геттеров/сеттеров):
class Product {
private _price: number;
@Min(0) // Декоратор аксессора
get price() {
return this._price;
}
set price(value: number) {
this._price = value;
}
}
В Node.js с TypeScript декораторы полностью поддерживаются с флагом experimentalDecorators: true в tsconfig.json. В чистом JavaScript (Node.js ≥ 14) можно использовать экспериментальные декораторы с флагом --experimental-decorators, но TypeScript предлагает более стабильную и богатую реализацию.
Практический пример из моего опыта — декоратор для логирования времени выполнения методов:
function LogExecutionTime() {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const start = Date.now();
const result = await originalMethod.apply(this, args);
const duration = Date.now() - start;
console.log(`${propertyKey} executed in ${duration}ms`);
return result;
};
return descriptor;
};
}
class UserService {
@LogExecutionTime()
async findUsers() {
// Длительная операция
return await db.users.findMany();
}
} Ответ 18+ 🔞
Ёпта, ну ты спросил — я тебе сейчас такую простыню накатал, что хоть в рамку вешай! Декораторы в TypeScript — это ж не только для классов, блядь. Это как швейцарский нож для разработчика, только без лезвия, которое постоянно теряется.
Смотри, в моих Node.js проектах я эти декораторы юзаю на все случаи жизни, прям овердохуища применений. Вот тебе полный разбор, чтоб ты не бздел от незнания.
1. Декораторы классов — это как наклейка «Хрупкое» на коробке, только для кода. Регистрируешь в DI, метаданные цепляешь — красота!
import { Injectable, Singleton } from 'tsyringe';
@Injectable() // Вот она, магия, ёпта!
@Singleton() // А можно и пачку навесить, как стикеров на чемодан
class DatabaseService {
constructor(private config: ConfigService) {}
async connect() {
return await mongoose.connect(this.config.databaseUrl);
}
}
2. Декораторы методов — тут вообще пиздопроебибна простор для фантазии. Логирование, кэш, валидация — всё в одну строку.
import { Get, Controller, UseGuards } from '@nestjs/common';
@Controller('users')
class UsersController {
@Get() // Говорим: этот метод — для GET-запросов
@UseGuards(AuthGuard) // И чтоб не лез всякий **пидарас шерстяной**
@CacheTTL(60) // И чтоб в кэше болтался минуту
async getAllUsers() {
return await this.userService.findAll();
}
}
3. Декораторы свойств — моя любимая тема. Сделал DTO, навесил валидацию — и можно спать спокойно, доверия ебать ноль к входящим данным.
import { Expose, Type } from 'class-transformer';
import { IsEmail, IsString } from 'class-validator';
class UserDto {
@Expose() // Это свойство наружу показываем
id: number;
@IsString() // Проверяем, что строка
@IsEmail() // И что почта, а не **манда с ушами**
email: string;
@Type(() => Date) // Автоматом в дату преобразуем
createdAt: Date;
}
4. Декораторы параметров — хитрая жопа, но удобная. Прямо в аргументы конструктора зависимости засунуть.
import { Inject } from '@nestjs/common';
class UserService {
constructor(
@Inject('USER_MODEL') // Говорим: дай сюда модель юзеров
private userModel: Model<User>,
@Inject(ConfigService) // А сюда — конфиг
private config: ConfigService
) {}
}
5. Декораторы аксессоров — для геттеров и сеттеров. Чтоб сеттер не записал какую-нибудь залупу конскую.
class Product {
private _price: number;
@Min(0) // Чтоб цена не ушла в минус, ёпта!
get price() {
return this._price;
}
set price(value: number) {
this._price = value;
}
}
В Node.js с TypeScript это всё работает на ура, надо только в tsconfig.json флажок experimentalDecorators: true поставить. В чистом JS, конечно, терпения ноль ебать — там флаг экспериментальный, но TypeScript всё делает цивильно.
А вот тебе, кстати, реальный пример из жизни — декоратор, который засекает, сколько метод работает. Прям волнение ебать, когда видишь, какой метод тормозит!
function LogExecutionTime() {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const start = Date.now();
const result = await originalMethod.apply(this, args);
const duration = Date.now() - start;
// Смотри, не **сам от себя охуел** от цифр
console.log(`${propertyKey} executed in ${duration}ms`);
return result;
};
return descriptor;
};
}
class UserService {
@LogExecutionTime() // Навесил — и профит!
async findUsers() {
// Какая-нибудь долгая операция с базой
return await db.users.findMany();
}
}
Короче, декораторы — это сила. Сначала кажется, что хуй с горы, но когда втянешься — без них как без рук. Главное — не переборщить, а то получится ёперный театр из аннотаций вместо кода.