Registry /
serialization / babel-plugin-transform-typescript-metadata
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
babel-plugin-transform-typescript-metadata
✓ // In your Babel configuration file (e.g., .babelrc.js or babel.config.js):
module.exports = {
plugins: [
"babel-plugin-transform-typescript-metadata",
// ... other plugins, ensuring this one is first
],
};
✗ import plugin from 'babel-plugin-transform-typescript-metadata'; // This is a Babel plugin, not intended for direct import in application code.
const plugin = require('babel-plugin-transform-typescript-metadata'); // Incorrect usage in application code; it's configured by Babel.
This package is a Babel plugin and is configured within your Babel configuration file, typically as a string identifier in the `plugins` array. It does not export symbols for direct `import` or `require` in your application's JavaScript/TypeScript code.
Demonstrates a TypeScript application using decorators for dependency injection, showcasing how `babel-plugin-transform-typescript-metadata` enables runtime type reflection. It includes an example with InversifyJS, illustrating both constructor and property injection, and explicitly retrieves emitted metadata via `Reflect.getMetadata`.
import 'reflect-metadata'; // Essential for runtime metadata access
import { injectable, inject } from 'inversify'; // Example: InversifyJS for DI
// Define an interface for clarity
interface Logger {
log(message: string): void;
}
// Implement the interface and make it injectable
@injectable()
class ConsoleLogger implements Logger {
private readonly prefix: string;
constructor(@inject('logPrefix') prefix: string) {
this.prefix = prefix;
}
log(message: string): void {
console.log(`[${this.prefix}] ${message}`);
}
}
// A service that depends on a Logger
@injectable()
class DataService {
@inject('Logger') // Property injection example
private readonly logger!: Logger;
private readonly apiUrl: string;
constructor(@inject('apiUrl') apiUrl: string) { // Constructor injection example
this.apiUrl = apiUrl;
}
fetchData(): void {
this.logger.log(`Fetching data from ${this.apiUrl}...`);
// Simulate fetching data
const data = { id: 1, name: 'Sample Data' };
this.logger.log(`Data received: ${JSON.stringify(data)}`);
// Demonstrate emitted metadata (runtime reflection)
console.log('\n--- Runtime Metadata for DataService.logger ---');
const loggerType = Reflect.getMetadata('design:type', DataService.prototype, 'logger');
console.log('design:type (logger):', loggerType ? loggerType.name : 'unknown');
console.log('\n--- Runtime Metadata for ConsoleLogger constructor ---');
const constructorParams = Reflect.getMetadata('design:paramtypes', ConsoleLogger);
console.log('design:paramtypes (ConsoleLogger):', constructorParams ? constructorParams.map((p: any) => p.name) : 'unknown');
}
}
// To run this, you would typically use a Babel setup:
// 1. Install dependencies: `npm install --save-dev @babel/core @babel/preset-typescript @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties`
// `npm install reflect-metadata inversify`
// 2. Configure Babel (e.g., in babel.config.js):
// module.exports = {
// plugins: [
// 'babel-plugin-transform-typescript-metadata',
// ['@babel/plugin-proposal-decorators', { 'legacy': true }],
// ['@babel/plugin-proposal-class-properties', { 'loose': true }],
// ],
// presets: [
// '@babel/preset-typescript',
// ],
// };
// --- Manual setup to run the example without a full Inversify container ---
// (In a real app, an Inversify container would handle instantiation and injection)
// Mock 'inject' for compile-time type checking and demonstration
class FakeInject { constructor(id: string) { return (target: any, key: string, index?: number) => {}; } }
const fakeInject = (id: string) => new FakeInject(id) as any;
// Manually create instances and inject for demonstration
const logPrefix = 'APP';
const consoleLogger: Logger = new ConsoleLogger(logPrefix);
const apiUrl = 'https://api.example.com/data';
const dataService = new DataService(apiUrl);
// Simulate property injection
(dataService as any).logger = consoleLogger;
dataService.fetchData();
Errors
Common errors & fixes
Error: Decorators are not valid here. This error usually occurs when the decorator plugin is not configured correctly or is placed in the wrong order.
The `babel-plugin-transform-typescript-metadata` is positioned incorrectly (after `@babel/plugin-proposal-decorators`) or `@babel/plugin-proposal-decorators` is missing `{'legacy': true}`.
fixIn your Babel config, ensure `babel-plugin-transform-typescript-metadata` is the first plugin listed, and `@babel/plugin-proposal-decorators` is configured as `['@babel/plugin-proposal-decorators', { 'legacy': true }]`. TypeError: Reflect.getMetadata is not a function
The `reflect-metadata` polyfill, which provides the `Reflect.getMetadata` function, has not been loaded at runtime.
fixInstall `reflect-metadata` (`npm install reflect-metadata`) and add `import 'reflect-metadata';` as the very first line in your application's main entry file (e.g., `src/main.ts`).
TypeError: Cannot read properties of undefined (reading 'constructor') or similar runtime errors when using decorated classes/properties.
This often indicates that the design-time metadata for a decorated class or property is missing or incorrect, typically because `reflect-metadata` was not loaded, or the Babel plugin failed to emit the metadata due to misconfiguration.
fixVerify that `reflect-metadata` is imported at the application's entry point and that the Babel plugin (`babel-plugin-transform-typescript-metadata`) is correctly configured (especially plugin order and `legacy: true` for decorators).
Audit
Dependencies
@babel/corerequiredRequired peer dependency for the Babel host environment.
reflect-metadataoptionalRuntime polyfill required by the application to consume the metadata emitted by the plugin. Must be installed separately by the consumer.