Are you sure you don't want to discover the perfect job opportunity? At JobPe, we help you
find the best career matches,
tailored to your skills and preferences. Don’t miss out on your dream job!
Login to
Please Verify Your Phone or Email
We have sent an OTP to your
contact. Please enter it below to verify.
Don't
have an
account yet? Sign
up
Already
have an
account?
Login
Alert
Your message here...
Confirm Action
Your notification message here...
Contact Us
For any questions
or assistance regarding
Customer Support,
Sales Inquiries, Technical Support, or General Inquiries,
our AI-powered team is here to help!
Decorators are special declarations that can be attached to class declarations, methods, properties, or parameters. They are enabled by setting 'experimentalDecorators: true' in tsconfig.json. Example: @decorator class Example {}. Decorators provide a way to add annotations and metadata to existing code.
TypeScript supports five types of decorators: 1) Class decorators (@classDecorator), 2) Method decorators (@methodDecorator), 3) Property decorators (@propertyDecorator), 4) Accessor decorators (@accessorDecorator), and 5) Parameter decorators (@parameterDecorator). Each type receives different arguments and can be used for different purposes.
Class decorators are declared before a class declaration and receive the constructor as an argument. Example: function logger(target: Function) { console.log(`Creating class: ${target.name}`); } @logger class Example {}. They can modify or replace the class definition and are useful for adding metadata or behavior to classes.
Method decorators are declared before method declarations and receive three arguments: target (prototype), propertyKey (method name), and descriptor (property descriptor). Example: function log(target: any, key: string, descriptor: PropertyDescriptor) { // Original method const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Calling ${key}`); return original.apply(this, args); }; }
reflect-metadata is a library that adds a polyfill for the Metadata Reflection API. It's used with decorators to add and read metadata about classes, methods, and properties. Enable with 'emitDecoratorMetadata: true' in tsconfig.json. Example: import 'reflect-metadata'; @Reflect.metadata('role', 'admin') class User {}
Property decorators receive two arguments: target (prototype) and propertyKey (property name), unlike method decorators which also receive a descriptor. Example: function validate(target: any, key: string) { let value = target[key]; Object.defineProperty(target, key, { get: () => value, set: (newValue) => { if (!newValue) throw new Error('Value cannot be null'); value = newValue; } }); }
Decorator factories are functions that return decorators and allow customization through parameters. Example: function log(prefix: string) { return function(target: any) { console.log(`${prefix}: ${target.name}`); }; } @log('MyApp') class Example {}. They provide a way to customize decorator behavior.
Parameter decorators are applied to method parameters and receive three arguments: target (prototype), methodName, and parameterIndex. Example: function required(target: Object, propertyKey: string, parameterIndex: number) { const requiredParams = Reflect.getMetadata('required', target, propertyKey) || []; requiredParams.push(parameterIndex); Reflect.defineMetadata('required', requiredParams, target, propertyKey); }
Accessor decorators are applied to getter/setter declarations and receive three arguments similar to method decorators. Example: function enumerable(value: boolean) { return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) { descriptor.enumerable = value; }; } They're useful for modifying accessor behavior.
Multiple decorators can be applied to a declaration in sequence. They are evaluated in reverse order (bottom to top). Example: @f @g class C {}. Evaluation order: g then f. For decorator factories: @f() @g() class C {}, the factories are evaluated in order (f then g) but the decorators in reverse order.
Metadata allows storing additional information about classes, methods, and properties that can be accessed at runtime. It's enabled with reflect-metadata. Example: Reflect.defineMetadata('validation', { required: true }, target, propertyKey); const metadata = Reflect.getMetadata('validation', target, propertyKey);
Validation decorators can be implemented using property or parameter decorators with metadata. Example: function required(target: any, propertyKey: string) { const validationMetadata = { required: true }; Reflect.defineMetadata('validation', validationMetadata, target, propertyKey); } class User { @required name: string; }
Common use cases include: 1) Logging and monitoring, 2) Property validation, 3) Dependency injection, 4) Method memoization, 5) Access control and authorization, 6) Class and property transformation, 7) API endpoint definition (e.g., in NestJS), 8) Observable properties (e.g., in Angular), 9) Type serialization/deserialization.
Decorators can implement dependency injection by using metadata to store and retrieve dependencies. Example: function Injectable() { return function(target: any) { Reflect.defineMetadata('injectable', true, target); }; } @Injectable() class Service {} This pattern is used in frameworks like Angular and NestJS.
Limitations include: 1) Experimental feature requiring compiler flag, 2) Can't decorate declarations in .d.ts files, 3) Limited to specific declaration types (class, method, property, parameter), 4) Can't access decorated values during declaration phase, 5) No direct way to decorate local variables or function declarations.
Memoization decorators cache function results based on arguments. Example: function memoize(target: any, key: string, descriptor: PropertyDescriptor) { const original = descriptor.value; const cache = new Map(); descriptor.value = function(...args: any[]) { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result = original.apply(this, args); cache.set(key, result); return result; }; }
Design-time type metadata is automatically generated when emitDecoratorMetadata is enabled. It includes type information for parameters, return types, and properties. Example: const paramTypes = Reflect.getMetadata('design:paramtypes', target, key); This is used by frameworks for dependency injection and validation.
Method override decorators can verify proper method overriding. Example: function override(target: any, key: string, descriptor: PropertyDescriptor) { const baseClass = Object.getPrototypeOf(target); if (!baseClass[key]) throw new Error(`${key} doesn't override any base method`); return descriptor; } class Child extends Parent { @override method() {} }
Best practices include: 1) Use decorator factories for configuration, 2) Keep decorators focused and single-purpose, 3) Handle errors gracefully, 4) Use meaningful names that describe behavior, 5) Document decorator requirements and effects, 6) Avoid side effects in decorator evaluation, 7) Use metadata for storing configuration, 8) Consider performance implications.
Lazy initialization decorators delay property initialization until first access. Example: function lazy<T>(initializer: () => T) { return function(target: any, key: string) { let value: T; Object.defineProperty(target, key, { get: () => { if (!value) value = initializer(); return value; } }); }; } class Example { @lazy(() => expensiveOperation()) value: string; }
Async operations in decorators require special handling since decorators run during class definition. Example: function asyncInit() { return function(target: any) { return class extends target { async init() { await super.init(); // Additional async initialization } }; }; } @asyncInit() class Service { async init() { /* ... */ } }
Key differences include: 1) Syntax variations, 2) TypeScript decorators are experimental while ES decorators are part of the standard, 3) Different metadata handling, 4) ES decorators have additional capabilities like decorating object literals, 5) TypeScript decorators may need updates to align with ES decorator standard when finalized.
Explore a wide range of interview questions for freshers and professionals, covering technical, business, HR, and management skills, designed to help you succeed in your job interview.
Are these questions suitable for beginners?
Yes, the questions include beginner-friendly content for freshers, alongside advanced topics for experienced professionals, catering to all career levels.
How can I prepare for technical interviews?
Access categorized technical questions with detailed answers, covering coding, algorithms, and system design to boost your preparation.
Are there resources for business and HR interviews?
Find tailored questions for business roles (e.g., finance, marketing) and HR roles (e.g., recruitment, leadership), perfect for diverse career paths.
Can I prepare for specific roles like consulting or management?
Yes, the platform offers role-specific questions, including case studies for consulting and strategic questions for management positions.
How often are the interview questions updated?
Questions are regularly updated to align with current industry trends and hiring practices, ensuring relevance.
Are there free resources for interview preparation?
Free access is available to a variety of questions, with optional premium resources for deeper insights.
How does this platform help with interview success?
Get expert-crafted questions, detailed answers, and tips, organized by category, to build confidence and perform effectively in interviews.