Ответ
В контексте TypeScript и Node.js под метаданными я понимаю информацию о типах, структурах или конфигурации, которая доступна во время выполнения (runtime) или используется инструментами на этапе компиляции.
1. Метаданные TypeScript (декораторы и reflect-metadata):
Это мощный механизм для добавления информации к классам, методам или свойствам, которую потом можно прочитать.
import 'reflect-metadata';
// Декоратор, который добавляет метаданные
function Log(target: any, key: string) {
const types = Reflect.getMetadata('design:type', target, key);
const paramtypes = Reflect.getMetadata('design:paramtypes', target, key);
console.log(`${key} type: ${types.name}, param types: ${paramtypes?.map(p => p.name)}`);
}
class MyService {
@Log
greet(name: string): string {
return `Hello, ${name}`;
}
}
// При запуске (с включенной опцией `emitDecoratorMetadata` в tsconfig.json)
// в консоль выведется: greet type: Function, param types: String
Где это применяется:
- Фреймворки: NestJS, TypeORM, class-validator активно используют декораторы и метаданные для dependency injection, описания моделей БД и валидации.
- Собственные валидаторы или сериализаторы: Можно создать декоратор
@MaxLength(10)и в runtime проверить значение поля.
2. Метаданные пакетов (package.json):
В Node.js package.json — это основные метаданные модуля. Я использую их для:
{
"name": "my-service",
"version": "1.0.0",
"engines": { "node": ">=18.0.0" }, // Метаданные о среде
"config": { "defaultPort": 3000 } // Кастомная конфигурация
}
Доступ через process.env.npm_package_config_defaultPort.
3. Метаданные в HTTP-запросах/ответах:
Заголовки (X-Request-Id, User-Agent) — это форма метаданных для отслеживания и логирования.
app.use((req, res, next) => {
req.id = uuid.v4(); // Добавляем метаданные к объекту запроса
res.setHeader('X-Response-Time', Date.now() - req.startTime);
next();
}); Ответ 18+ 🔞
Вот, смотри, объясняю про метаданные в TypeScript и Node.js, как есть. Это же просто информация о твоём коде или приложении, которая болтается где-то рядом — либо когда код уже работает, либо когда компилятор его жуёт. Типа справки о самом себе.
1. Метаданные TypeScript (эти ваши декораторы и reflect-metadata):
Ёпта, это вообще мощнейшая штука, если уметь готовить. Позволяет навешивать на классы, методы или свойства дополнительные бирочки с информацией, которую потом можно вытащить и посмотреть.
import 'reflect-metadata';
// Вот делаем простой декоратор, который будет метаданные цеплять
function Log(target: any, key: string) {
const types = Reflect.getMetadata('design:type', target, key);
const paramtypes = Reflect.getMetadata('design:paramtypes', target, key);
console.log(`${key} type: ${types.name}, param types: ${paramtypes?.map(p => p.name)}`);
}
class MyService {
@Log
greet(name: string): string {
return `Hello, ${name}`;
}
}
// Главное, не забудь в `tsconfig.json` опцию `emitDecoratorMetadata` включить, а то нихуя не заработает.
// Тогда при запуске в консоль вывалится: greet type: Function, param types: String
Где это всё, блядь, применяется на практике?
- Всякие модные фреймворки: NestJS, TypeORM, class-validator — они на этом просто живут. Внедрение зависимостей, описание моделей для базы, валидация — всё через декораторы и метаданные, овердохуища удобства.
- Свои велосипеды: Захотел сделать валидатор — пожалуйста. Напишешь декоратор
@MaxLength(10), навесишь на поле, и потом в рантайме проверишь, что пользователь не насрал туда строку в сто символов.
2. Метаданные пакетов (этот вездесущий package.json):
Ну, тут всё просто, как три копейки. В Node.js package.json — это и есть главные метаданные твоего модуля. Я, например, ими пользуюсь вот для чего:
{
"name": "my-service",
"version": "1.0.0",
"engines": { "node": ">=18.0.0" }, // Метаданные о том, на какой версии Node это говно должно работать
"config": { "defaultPort": 3000 } // А это уже моя кастомная хрень для конфигурации
}
Достучаться до этого можно, например, через process.env.npm_package_config_defaultPort. Удобно, ёпта.
3. Метаданные в HTTP-запросах и ответах:
А это вообще классика. Все эти заголовки — X-Request-Id, User-Agent — они же и есть чистейшие метаданные! Нужны для отслеживания сквозных запросов или логирования.
app.use((req, res, next) => {
req.id = uuid.v4(); // Вот, прилепили к объекту запроса свою метку — это и есть метаданные
res.setHeader('X-Response-Time', Date.now() - req.startTime); // И в ответ тоже можно воткнуть
next();
});
Короче, суть в том, что метаданные — это не какая-то хитрая жопа, а просто дополнительная информация, которая помогает твоему коду быть умнее и знать о себе больше. Главное — не переборщить, а то можно так задекорировать, что сам потом разбираться будешь, как в джунглях.