TypeScript এর Decorators এবং Metadata

টাইপস্ক্রিপ্ট (Typescript) - Web Development

232

Decorators TypeScript-এ একটি powerful ফিচার, যা কোডের বিভিন্ন অংশ (যেমন ক্লাস, মেথড, প্রপার্টি বা প্যারামিটার) এর ওপর অতিরিক্ত আচরণ বা লজিক প্রয়োগ করতে ব্যবহার করা হয়। এগুলো বিশেষত মেটাডেটা ব্যবহার করার ক্ষেত্রে গুরুত্বপূর্ণ, কারণ আপনি কোডের বিভিন্ন অংশের মেটাডেটা সংগ্রহ এবং ব্যবস্থাপনা করতে পারেন।


১. ডেকোরেটর (Decorators) কী?

ডেকোরেটর TypeScript-এ একটি special type of function, যা ক্লাস, মেথড, প্রপার্টি, অথবা প্যারামিটারগুলোর ওপর প্রয়োগ করা হয়। এটি আপনাকে সেই ক্লাস বা মেথডের আচরণ পরিবর্তন করতে বা অতিরিক্ত আচরণ যোগ করতে সহায়তা করে। ডেকোরেটর ব্যবহার করা হয় অ্যানোটেশন বা মেটাডেটা সংযোজনের জন্য।

ডেকোরেটর ব্যবহারের জন্য, TypeScript-এ experimentalDecorators অপশনটি সক্রিয় করা প্রয়োজন, যা tsconfig.json ফাইলে দেওয়া যায়।

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

২. ডেকোরেটর টাইপসমূহ

TypeScript-এ বিভিন্ন ধরনের ডেকোরেটর রয়েছে, যেমন:

  • ক্লাস ডেকোরেটর (Class Decorator): ক্লাসের ওপর প্রয়োগ করা হয়।
  • মেথড ডেকোরেটর (Method Decorator): মেথডের ওপর প্রয়োগ করা হয়।
  • প্রপার্টি ডেকোরেটর (Property Decorator): ক্লাসের প্রপার্টির ওপর প্রয়োগ করা হয়।
  • প্যারামিটার ডেকোরেটর (Parameter Decorator): ফাংশন বা মেথডের প্যারামিটারের ওপর প্রয়োগ করা হয়।

৩. ক্লাস ডেকোরেটর (Class Decorator)

ক্লাস ডেকোরেটর হল একটি ফাংশন যা ক্লাসের ডিফিনিশনে প্রয়োগ করা হয়। এটি সাধারণত ক্লাসের কনস্ট্রাকটরের ওপর কাজ করে এবং আপনি এই ডেকোরেটর ব্যবহার করে ক্লাসের কার্যকারিতা পরিবর্তন করতে পারেন।

উদাহরণ:

function LogClass(target: Function) {
  console.log(`Class ${target.name} is being created`);
}

@LogClass
class Person {
  constructor(public name: string) {}
}

const person = new Person("Alice");  // Output: Class Person is being created

এখানে, LogClass ক্লাস ডেকোরেটর Person ক্লাসের ওপর প্রয়োগ করা হয়েছে। ক্লাসটি তৈরি করার সময় ডেকোরেটরটি একটি মেসেজ লগ করবে।


৪. মেথড ডেকোরেটর (Method Decorator)

মেথড ডেকোরেটর মেথডের ওপর প্রয়োগ করা হয়। এটি মেথডের আচরণ বা কার্যকারিতা পরিবর্তন করতে সাহায্য করে। আপনি মেথডের কাজ বা আর্গুমেন্টগুলোর উপর অতিরিক্ত লজিক প্রয়োগ করতে পারেন।

উদাহরণ:

function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function(...args: any[]) {
    console.log(`Calling method ${propertyKey} with arguments: ${args}`);
    return originalMethod.apply(this, args);
  };
}

class Calculator {
  @LogMethod
  add(a: number, b: number): number {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3);  // Output: Calling method add with arguments: 2,3

এখানে, LogMethod মেথড ডেকোরেটর add মেথডের ওপর প্রয়োগ করা হয়েছে। এটি মেথডটি কল করার সময় আর্গুমেন্টগুলো লগ করবে।


৫. প্রপার্টি ডেকোরেটর (Property Decorator)

প্রপার্টি ডেকোরেটর ক্লাসের প্রপার্টির ওপর প্রয়োগ করা হয়। এটি সাধারণত ক্লাসের প্রপার্টির মেটাডেটা পরিচালনা করতে ব্যবহৃত হয়।

উদাহরণ:

function PropertyLogger(target: any, propertyKey: string) {
  let value = target[propertyKey];

  const getter = () => {
    console.log(`Getting value of ${propertyKey}: ${value}`);
    return value;
  };

  const setter = (newValue: any) => {
    console.log(`Setting value of ${propertyKey} to: ${newValue}`);
    value = newValue;
  };

  Object.defineProperty(target, propertyKey, {
    get: getter,
    set: setter,
  });
}

class Employee {
  @PropertyLogger
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

const emp = new Employee("John");
emp.name = "Doe";  // Output: Setting value of name to: Doe
console.log(emp.name);  // Output: Getting value of name: Doe

এখানে, PropertyLogger ডেকোরেটর name প্রপার্টির ওপর প্রয়োগ করা হয়েছে। এটি প্রপার্টির সেট এবং গেট অপারেশনগুলোর ওপর কাস্টম লজিক প্রয়োগ করছে।


৬. প্যারামিটার ডেকোরেটর (Parameter Decorator)

প্যারামিটার ডেকোরেটর ফাংশন বা মেথডের প্যারামিটারগুলোর ওপর প্রয়োগ করা হয়। এটি প্যারামিটার সম্পর্কে মেটাডেটা সংরক্ষণ বা পরিচালনা করতে ব্যবহৃত হয়।

উদাহরণ:

function LogParameter(target: any, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} is being decorated`);
}

class Greeting {
  greet(@LogParameter message: string): void {
    console.log(message);
  }
}

const greeting = new Greeting();
greeting.greet("Hello, TypeScript!");  // Output: Parameter at index 0 in method greet is being decorated

এখানে, LogParameter প্যারামিটার ডেকোরেটর greet মেথডের প্যারামিটার message এর ওপর প্রয়োগ করা হয়েছে।


৭. মেটাডেটা (Metadata) এবং ডেকোরেটরস

TypeScript-এ মেটাডেটা ব্যবহার করে আপনি ডেকোরেটরস দ্বারা সংরক্ষিত তথ্য সংগ্রহ করতে পারেন। মেটাডেটা সাধারণত Reflect Metadata লাইব্রেরির মাধ্যমে পরিচালিত হয়।

উদাহরণ:

import "reflect-metadata";

function MyDecorator(target: any, key: string) {
  Reflect.defineMetadata("customMetadata", "This is a custom metadata", target, key);
}

class Example {
  @MyDecorator
  myMethod() {}
}

const metadata = Reflect.getMetadata("customMetadata", Example.prototype, "myMethod");
console.log(metadata);  // Output: This is a custom metadata

এখানে, Reflect.defineMetadata দ্বারা মেটাডেটা যোগ করা হয়েছে এবং Reflect.getMetadata দ্বারা সেটি রিট্রিভ করা হয়েছে।


সারাংশ

TypeScript-এ ডেকোরেটর এবং মেটাডেটা শক্তিশালী টুলস, যা কোডে অতিরিক্ত ফিচার বা আচরণ যুক্ত করতে সহায়তা করে। ডেকোরেটর ব্যবহার করে আপনি ক্লাস, মেথড, প্রপার্টি এবং প্যারামিটারগুলোর ওপর কার্যকরী লজিক প্রয়োগ করতে পারেন, যা কোডের রিডেবিলিটি এবং মেইনটেনেবিলিটি উন্নত করে।

Content added By

TypeScript এ ডেকোরেটরস এমন একটি শক্তিশালী বৈশিষ্ট্য যা ক্লাস, প্রোপার্টি, মেথড এবং প্যারামিটারগুলির উপর আচরণ কাস্টমাইজ বা পরিবর্তন করতে ব্যবহৃত হয়। এটি একটি মেটা-প্রোগ্রামিং কৌশল, যা অ্যাপ্লিকেশন ডেভেলপমেন্টে বিভিন্ন ধরনের কাস্টম লজিক প্রয়োগ করতে সাহায্য করে। TypeScript এর ডেকোরেটরস প্যাটার্ন মূলত বিচ্ছিন্ন ফাংশন হিসাবে কাজ করে, যা ক্লাস বা মেথডের কাঠামো বা আচরণ পরিবর্তন করে।

ডেকোরেটরস ব্যবহার করতে আপনার tsconfig.jsonexperimentalDecorators অপশনটি true করতে হবে।


১. ক্লাস ডেকোরেটর (Class Decorators)

ক্লাস ডেকোরেটর হল এমন একটি ফাংশন যা ক্লাস ডেফিনিশনকে কাস্টমাইজ করে। এটি সাধারণত একটি ক্লাসের কন্সট্রাকটর ফাংশনকে টার্গেট করে। ক্লাস ডেকোরেটর একটি ফাংশন গ্রহণ করে এবং সেটি ক্লাসের ইনস্ট্যান্স তৈরি হওয়া পর্যন্ত কার্যকর হয়।

উদাহরণ:

function LogClass(target: Function) {
  console.log(`Class created: ${target.name}`);
}

@LogClass
class Person {
  constructor(public name: string, public age: number) {}
}

const person = new Person("John", 30);  // আউটপুট: "Class created: Person"

এখানে, @LogClass ডেকোরেটরটি Person ক্লাসের ওপর প্রয়োগ করা হয়েছে। ক্লাসের ইনস্ট্যান্স তৈরি হওয়ার আগে এই ডেকোরেটরটি কন্সট্রাকটরের মাধ্যমে কার্যকর হবে।


২. মেথড ডেকোরেটর (Method Decorators)

মেথড ডেকোরেটর ফাংশনটি একটি ক্লাসের মেথডের ওপর কাজ করে এবং মেথডটির কার্যকারিতা পরিবর্তন বা কাস্টমাইজ করতে ব্যবহৃত হয়। এটি সাধারণত মেথডের ডেসক্রিপটর (descriptor)কে গ্রহণ করে এবং মেথডটির আচরণ পরিবর্তন করে।

উদাহরণ:

function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;
  
  descriptor.value = function (...args: any[]) {
    console.log(`Called method ${propertyKey} with arguments: ${args}`);
    return originalMethod.apply(this, args);
  };
}

class Person {
  constructor(public name: string) {}

  @LogMethod
  greet(message: string) {
    console.log(`${this.name} says: ${message}`);
  }
}

const person = new Person("Alice");
person.greet("Hello!");  // আউটপুট: "Called method greet with arguments: [ 'Hello!' ]"

এখানে @LogMethod ডেকোরেটরটি greet মেথডের ওপর প্রয়োগ করা হয়েছে। মেথডটি কল করার সময়, এটি প্রথমে মেথডের নাম এবং আর্গুমেন্টগুলি লগ করবে এবং তারপর আসল মেথডটি কার্যকর হবে।


৩. প্রোপার্টি ডেকোরেটর (Property Decorators)

প্রোপার্টি ডেকোরেটর ফাংশনটি একটি ক্লাসের প্রোপার্টি (যেমন: বৈশিষ্ট্য বা ভেরিয়েবল)কে কাস্টমাইজ করে। এটি সাধারণত প্রোপার্টির উপর কিছু অতিরিক্ত আচরণ যোগ করতে ব্যবহৃত হয়।

উদাহরণ:

function LogProperty(target: any, propertyKey: string) {
  let value: string;

  const getter = () => value;
  const setter = (newValue: string) => {
    console.log(`Setting value of ${propertyKey} to ${newValue}`);
    value = newValue;
  };

  Object.defineProperty(target, propertyKey, { get: getter, set: setter });
}

class Person {
  @LogProperty
  public name: string;

  constructor(name: string) {
    this.name = name;
  }
}

const person = new Person("John");
person.name = "Alice";  // আউটপুট: "Setting value of name to Alice"

এখানে @LogProperty ডেকোরেটরটি name প্রোপার্টির ওপর প্রয়োগ করা হয়েছে। যখন আপনি name প্রোপার্টির মান পরিবর্তন করবেন, তখন এটি নতুন মান সেট করার আগে লগ করবে।


৪. প্যারামিটার ডেকোরেটর (Parameter Decorators)

প্যারামিটার ডেকোরেটর ব্যবহার করে আপনি একটি মেথডের প্যারামিটারকে কাস্টমাইজ বা অ্যাসাইন করতে পারেন। প্যারামিটার ডেকোরেটর সাধারণত মেথডের প্যারামিটার সহ কোডের আরো লজিক প্রয়োগ করতে ব্যবহৃত হয়।

উদাহরণ:

function LogParameter(target: any, propertyKey: string, parameterIndex: number) {
  const existingMetadata = Reflect.getOwnMetadata("log_parameters", target, propertyKey) || [];
  existingMetadata.push(parameterIndex);
  Reflect.defineMetadata("log_parameters", existingMetadata, target, propertyKey);
}

class Person {
  constructor(public name: string) {}

  greet(@LogParameter message: string) {
    console.log(`${this.name} says: ${message}`);
  }
}

const person = new Person("Alice");
person.greet("Hello!");

// Log the metadata
const metadata = Reflect.getOwnMetadata("log_parameters", person, "greet");
console.log(metadata); // প্যারামিটার ইনডেক্সটি দেখাবে

এখানে @LogParameter ডেকোরেটরটি greet মেথডের message প্যারামিটারের ওপর প্রয়োগ করা হয়েছে। এটি প্যারামিটার ইনডেক্সটিকে মেটাডেটা হিসেবে রেকর্ড করে, যাতে আপনি পরে প্যারামিটারগুলির সাথে কাজ করতে পারেন।


ডেকোরেটরসের ব্যবহারিক প্রয়োগ

ডেকোরেটরস আপনাকে অ্যাপ্লিকেশনের উন্নত বৈশিষ্ট্য যেমন লগিং, কেশিং, ব্যতিক্রম হ্যান্ডলিং, অথেনটিকেশন, এবং আরও অনেক কিছু কাস্টমাইজ করতে সাহায্য করে। TypeScript ডেকোরেটরস ব্যবহার করার ফলে কোড আরও পরিষ্কার, শক্তিশালী এবং টাইপ নিরাপদ হয়।

এছাড়া, ডেকোরেটরসকে ব্যবহার করে আপনি ক্লাসের মধ্যে অবজেক্ট স্টেট ম্যানেজমেন্ট, মেথড ট্রেসিং, এবং ডাটা ভ্যালিডেশন সহজেই বাস্তবায়ন করতে পারেন।


সারাংশ

TypeScript এর ডেকোরেটরস একটি শক্তিশালী বৈশিষ্ট্য যা ক্লাস, প্রোপার্টি, মেথড এবং প্যারামিটারগুলির আচরণ কাস্টমাইজ করতে ব্যবহৃত হয়। এটি মেটা-প্রোগ্রামিং টেকনিকের অংশ এবং প্রোগ্রামিংয়ের দক্ষতা বৃদ্ধি করতে সাহায্য করে। ডেকোরেটরসের মাধ্যমে কোডের কার্যকারিতা এবং নিরাপত্তা আরও উন্নত করা যায়।

Content added By

TypeScript Metadata Reflection API একটি বিশেষ ফিচার যা ক্লাস, প্রোপার্টি, মেথড এবং প্যারামিটার সম্পর্কিত মেটাডেটা (অর্থাৎ, টাইপ সম্পর্কিত তথ্য) সংগ্রহ এবং ব্যবহারের সুবিধা দেয়। এটি TypeScript প্রোগ্রামিংয়ে রিফ্লেকশন (Reflection) এর মাধ্যমে মেটাডেটা এক্সেস করতে এবং কোডের আচরণ বা কাঠামো প্রোগ্রাম্যাটিকভাবে পরিবর্তন করতে ব্যবহৃত হয়।

১. Metadata Reflection API এর পরিচিতি

TypeScript মেটাডেটা রিফ্লেকশন সাধারণত ডেকোরেটর এবং রিফ্লেকশন ব্যবহার করে, যা মেটাডেটা সংগ্রহ এবং সংরক্ষণ করার জন্য বিশেষ কৌশল সরবরাহ করে। reflect-metadata লাইব্রেরিটি TypeScript-এ রিফ্লেকশন কার্যকলাপ পরিচালনার জন্য ব্যবহৃত হয়। এটি ES7 বা TypeScript ডেকোরেটর সমর্থন করে এবং টাইপ মেটাডেটার সঙ্গে ইন্টারঅ্যাকশন করার জন্য প্রয়োজনীয় ফিচারগুলো প্রদান করে।

TypeScript এ মেটাডেটা রিফ্লেকশন ব্যবহার করতে হলে reflect-metadata প্যাকেজটি ইনস্টল করা প্রয়োজন।

reflect-metadata ইনস্টল করা

npm install reflect-metadata

এছাড়া, TypeScript কনফিগারেশন ফাইলে experimentalDecorators এবং emitDecoratorMetadata অপশনগুলো সক্ষম করতে হবে।

tsconfig.json উদাহরণ:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

২. Metadata Reflection API এর মূল ফাংশন

TypeScript এ মেটাডেটা রিফ্লেকশন করার জন্য কিছু প্রধান ফাংশন ব্যবহার করা হয়:

  • Reflect.metadata(metadataKey, metadataValue) – ডেকোরেটরের মাধ্যমে মেটাডেটা সেট করা।
  • Reflect.getMetadata(metadataKey, target, targetKey) – মেটাডেটা রিড করা।
  • Reflect.hasMetadata(metadataKey, target, targetKey) – মেটাডেটা উপস্থিতি চেক করা।

৩. উদাহরণ: মেটাডেটা রিফ্লেকশন

৩.১. ডেকোরেটর ব্যবহার করে মেটাডেটা সেট করা

প্রথমে, আপনি @Reflect.metadata ডেকোরেটর ব্যবহার করে মেটাডেটা সংরক্ষণ করতে পারেন।

import "reflect-metadata";

function Role(role: string) {
  return function(target: any, key: string | symbol) {
    Reflect.metadata("role", role)(target, key);
  };
}

class User {
  @Role("admin")
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

এখানে:

  • Role ডেকোরেটরটি name প্রোপার্টির জন্য মেটাডেটা হিসেবে "admin" সংরক্ষণ করছে।

৩.২. মেটাডেটা এক্সেস করা

মেটাডেটা সেট করার পর, আপনি Reflect.getMetadata ফাংশন ব্যবহার করে সেটি রিড করতে পারেন।

const user = new User("Alice");

// মেটাডেটা রিড করা
const role = Reflect.getMetadata("role", user, "name");
console.log(role);  // Output: admin

এখানে:

  • Reflect.getMetadata ব্যবহার করে name প্রোপার্টির জন্য সংরক্ষিত "role" মেটাডেটা রিড করা হচ্ছে এবং এটি "admin" রিটার্ন করছে।

৪. মেটাডেটা রিফ্লেকশন দিয়ে ক্লাসের তথ্য সংগ্রহ

আপনি পুরো ক্লাসের জন্যও মেটাডেটা সংগ্রহ করতে পারেন, যেমন কোন প্রোপার্টি বা মেথডে ডেকোরেটর অ্যাপ্লাই করা হয়েছে।

উদাহরণ: মেথড এবং প্যারামিটার মেটাডেটা

import "reflect-metadata";

function Log(target: any, key: string, descriptor: PropertyDescriptor) {
  Reflect.metadata("log", "Logging Method")(target, key);
}

class Product {
  @Log
  calculatePrice(price: number): number {
    return price * 1.2;
  }
}

const product = new Product();
const logMetadata = Reflect.getMetadata("log", product, "calculatePrice");
console.log(logMetadata);  // Output: Logging Method

এখানে:

  • Log ডেকোরেটরটি calculatePrice মেথডের জন্য মেটাডেটা হিসেবে "Logging Method" যোগ করছে।
  • পরে, Reflect.getMetadata ব্যবহার করে এই মেটাডেটা রিড করা হয়।

৫. Metadata Reflection API এর ব্যবহার

Metadata Reflection API সাধারণত ডাইনামিক ক্লাস কনফিগারেশন, ভ্যালিডেশন, ডেটাবেস ORM, ডিপেনডেন্সি ইনজেকশন এবং প্রপার্টি বা মেথডের আচরণ কাস্টমাইজ করতে ব্যবহৃত হয়।

উদাহরণ: ডিপেনডেন্সি ইনজেকশন

ডিপেনডেন্সি ইনজেকশন বা DI সিস্টেম তৈরি করতে মেটাডেটা রিফ্লেকশন ব্যবহার করা যায়। যেমন:

import "reflect-metadata";

class Service {
  sayHello() {
    console.log("Hello from Service!");
  }
}

function Injectable(target: any) {
  Reflect.defineMetadata("injectable", true, target);
}

@Injectable
class App {
  constructor(private service: Service) {}

  run() {
    this.service.sayHello();
  }
}

const app = new App(new Service());
app.run();  // Output: Hello from Service!

এখানে:

  • Injectable ডেকোরেটরটি ক্লাসে মেটাডেটা সংরক্ষণ করছে এবং ডিপেনডেন্সি ইনজেকশন ব্যবস্থা তৈরি করা হচ্ছে।

TypeScript Metadata Reflection API ডেকোরেটর এবং রিফ্লেকশন ব্যবহার করে কোডের মেটাডেটা সংগ্রহ এবং পরিবর্তন করতে একটি শক্তিশালী পদ্ধতি প্রদান করে। এটি বিশেষভাবে অ্যাডভান্সড ফিচার এবং লাইব্রেরি তৈরি করার জন্য উপকারী, যেমন ডিপেনডেন্সি ইনজেকশন, ORM এবং ক্লাস লেভেল কনফিগারেশন।

Content added By

TypeScript-এ ডেকোরেটরস এমন একটি ফিচার যা ক্লাস, মেথড, প্রোপার্টি, প্যারামিটার ইত্যাদির উপরে কাস্টম আচরণ যোগ করতে সাহায্য করে। এটি একটি বিশেষ ফাংশন যা নির্দিষ্ট উপাদানের আচরণ পরিবর্তন বা প্রসারিত করতে ব্যবহৃত হয়। TypeScript-এ কাস্টম ডেকোরেটরস তৈরি এবং ব্যবহার করা বেশ শক্তিশালী একটি কৌশল, যা আপনার কোডকে আরও নমনীয় এবং কার্যকরী করে তুলতে পারে।


১. ডেকোরেটরস কী?

ডেকোরেটরস হল এমন ফাংশন যা ক্লাস, মেথড, প্রোপার্টি বা প্যারামিটারগুলোর আচরণ পরিবর্তন করতে ব্যবহৃত হয়। ডেকোরেটরস মূলত মেটা-প্রোগ্রামিং এর একটি অংশ, যা আপনাকে কোডের আচরণ নিয়ন্ত্রণ এবং প্রসারিত করার সুযোগ দেয়। TypeScript-এ ডেকোরেটরস ES7 থেকে চালু করা হয়েছিল এবং এতে ক্লাস ডেকোরেটর, মেথড ডেকোরেটর, প্রপার্টি ডেকোরেটর এবং প্যারামিটার ডেকোরেটর অন্তর্ভুক্ত থাকে।


২. ডেকোরেটরস এর ধরন

TypeScript-এ চারটি প্রধান ধরনের ডেকোরেটরস রয়েছে:

  1. ক্লাস ডেকোরেটর (Class Decorators)
  2. মেথড ডেকোরেটর (Method Decorators)
  3. প্রপার্টি ডেকোরেটর (Property Decorators)
  4. প্যারামিটার ডেকোরেটর (Parameter Decorators)

৩. কাস্টম ডেকোরেটর তৈরি এবং ব্যবহারের নিয়ম

১. ক্লাস ডেকোরেটর

ক্লাস ডেকোরেটর একটি ফাংশন যা ক্লাসের উপরে প্রয়োগ করা হয়। এটি সাধারণত ক্লাসের আচরণ পরিবর্তন বা তার মেটাডেটা সংযুক্ত করার জন্য ব্যবহৃত হয়।

function logClass(target: Function) {
  console.log(`Class created: ${target.name}`);
}

@logClass
class Person {
  constructor(public name: string) {}
}

const person = new Person("John");

এখানে, logClass একটি ক্লাস ডেকোরেটর যা Person ক্লাসের ওপর প্রয়োগ করা হয়েছে। এটি ক্লাস তৈরি হওয়ার সময় ক্লাসের নাম লগ করবে।


২. মেথড ডেকোরেটর

মেথড ডেকোরেটর একটি ফাংশন যা ক্লাসের মেথডে ব্যবহৃত হয়। এটি মেথডের আচরণ পরিবর্তন বা তার লগিক যোগ করার জন্য ব্যবহৃত হতে পারে।

function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args: any[]) {
    console.log(`Called method: ${propertyKey} with arguments: ${args}`);
    return originalMethod.apply(this, args);
  };

  return descriptor;
}

class Calculator {
  @logMethod
  add(a: number, b: number): number {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3);  // এটি "Called method: add with arguments: [2, 3]" মুদ্রণ করবে।

এখানে, logMethod ডেকোরেটরটি add মেথডের উপরে প্রয়োগ করা হয়েছে। এটি মেথডের আর্গুমেন্ট এবং মেথড কল হওয়ার সময় লগ করবে।


৩. প্রপার্টি ডেকোরেটর

প্রপার্টি ডেকোরেটর ক্লাসের প্রপার্টি বা ফিল্ডের উপর প্রয়োগ করা হয়। এটি প্রপার্টির সেটার এবং গেটারের আচরণ পরিবর্তন করতে ব্যবহৃত হয়।

function logProperty(target: any, propertyKey: string) {
  let value = target[propertyKey];

  const getter = () => {
    console.log(`Getting value of ${propertyKey}: ${value}`);
    return value;
  };

  const setter = (newValue: any) => {
    console.log(`Setting value of ${propertyKey}: ${newValue}`);
    value = newValue;
  };

  Object.defineProperty(target, propertyKey, {
    get: getter,
    set: setter,
  });
}

class Person {
  @logProperty
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

const person = new Person("John");
person.name = "Alice";  // এটি "Setting value of name: Alice" মুদ্রণ করবে।
console.log(person.name);  // এটি "Getting value of name: Alice" মুদ্রণ করবে।

এখানে, logProperty ডেকোরেটরটি name প্রপার্টির জন্য একটি কাস্টম গেটার এবং সেটার তৈরি করেছে।


৪. প্যারামিটার ডেকোরেটর

প্যারামিটার ডেকোরেটর একটি ফাংশন যা ক্লাসের মেথডের প্যারামিটারগুলোর ওপর প্রয়োগ করা হয়। এটি প্যারামিটার সম্পর্কিত মেটাডেটা যোগ করার জন্য ব্যবহার করা হয়।

function logParameter(target: any, methodName: string, parameterIndex: number) {
  console.log(`Parameter at index ${parameterIndex} in method ${methodName} is being logged.`);
}

class Person {
  greet(@logParameter message: string) {
    console.log(message);
  }
}

const person = new Person();
person.greet("Hello, World!");

এখানে, logParameter ডেকোরেটরটি greet মেথডের প্যারামিটার message এর ওপর প্রয়োগ করা হয়েছে। এটি প্যারামিটার ইনডেক্স লগ করবে।


৪. ডেকোরেটর ব্যবহার করার নিয়মাবলী

  • ডেকোরেটরগুলি শুধুমাত্র ক্লাস, মেথড, প্রপার্টি এবং প্যারামিটারগুলোর উপর প্রয়োগ করা যায়।
  • ডেকোরেটরসকে টাইপস্ক্রিপ্ট কম্পাইলারের experimentalDecorators অপশন চালু করার মাধ্যমে সক্রিয় করতে হয়। এর জন্য tsconfig.json ফাইলে নিচের কনফিগারেশনটি রাখতে হবে:
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

TypeScript-এ কাস্টম ডেকোরেটরস তৈরি এবং ব্যবহার করা কোডের পুনঃব্যবহারযোগ্যতা এবং স্বচ্ছতা বাড়াতে সাহায্য করে। এটি মেটা-প্রোগ্রামিংয়ের একটি শক্তিশালী টুল, যা ক্লাসের আচরণ কাস্টমাইজ করার জন্য খুবই উপকারী। তবে, এর ব্যবহার সঠিকভাবে কনফিগার করতে হয় এবং TypeScript-এ এর সঠিক সমর্থন থাকতে হবে।

Content added By

Decorators TypeScript এবং ES7 এর একটি শক্তিশালী ফিচার যা ক্লাস, মেথড, প্রপার্টি, অথবা প্যারামিটারদের ওপর অতিরিক্ত ফাংশনালিটি যোগ করতে ব্যবহৃত হয়। এটি একটি বিশেষ ধরনের ফাংশন যা ক্লাস বা তার সদস্যদের (properties, methods) ওপর অ্যাপ্লাই হয় এবং তাদের আচরণ পরিবর্তন বা প্রসারিত করে। Decorators মূলত ক্লাসের বা মেথডের আচরণকে ডাইনামিকালি পরিবর্তন করতে ব্যবহৃত হয়।

TypeScript এ Decorators ES6 এবং পরবর্তী সংস্করণে স্বীকৃত হলেও, এটি একটি experimental ফিচার হিসেবে বিবেচিত হয় এবং tsconfig.jsonexperimentalDecorators অপশন চালু করতে হয়।


১. Decorator চালু করা

TypeScript এ Decorators ব্যবহার করতে হলে প্রথমে tsconfig.json ফাইলে experimentalDecorators অপশনটি true করতে হয়।

উদাহরণ: tsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "target": "es6"
  }
}

২. Decorator কি এবং কিভাবে কাজ করে?

Decorator একটি বিশেষ ধরনের ফাংশন যা ক্লাস, মেথড, প্রপার্টি অথবা প্যারামিটারকে পরিবর্তন বা প্রসারিত করতে ব্যবহৃত হয়। এটি সাধারণত একটি আর্গুমেন্ট হিসেবে ক্লাসের অবজেক্ট বা মেথডের প্রপার্টি নেয় এবং এর ওপর কিছু কাস্টম লজিক প্রয়োগ করে।

৩. Decorator এর টাইপস

TypeScript এ কয়েকটি ধরনের Decorators ব্যবহার করা হয়:

  1. Class Decorators: ক্লাসের উপরে একটি ডেকোরেটর অ্যাপ্লাই হয়।
  2. Method Decorators: মেথডের উপরে একটি ডেকোরেটর অ্যাপ্লাই হয়।
  3. Property Decorators: প্রপার্টির উপরে একটি ডেকোরেটর অ্যাপ্লাই হয়।
  4. Parameter Decorators: প্যারামিটারের উপরে একটি ডেকোরেটর অ্যাপ্লাই হয়।

৪. Class Decorators

Class Decorators ক্লাসের পুরো ব্যবহারের উপর কার্যকর হয় এবং এটি ক্লাসের কনস্ট্রাকটর ফাংশনকে পরিবর্তন বা প্রসারিত করতে পারে।

উদাহরণ: Class Decorator

function Injectable(target: Function) {
  console.log(`Class ${target.name} is Injectable`);
}

@Injectable
class MyService {
  constructor() {
    console.log("MyService instantiated");
  }
}

const service = new MyService();

এখানে:

  • Injectable একটি ডেকোরেটর যা MyService ক্লাসের উপরে প্রয়োগ করা হয়েছে।
  • এই ডেকোরেটরটি কনস্ট্রাকটরের ওপর কার্যকর হয়েছে এবং ক্লাসের ইনস্ট্যান্স তৈরি হলে কনসোলে একটি বার্তা প্রদর্শন করবে।

৫. Method Decorators

Method Decorators একটি মেথডের উপর কার্যকর হয় এবং মেথডের আচরণ পরিবর্তন বা প্রসারিত করতে পারে।

উদাহরণ: Method Decorator

function Log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;
  
  descriptor.value = function (...args: any[]) {
    console.log(`Method ${propertyName} called with args: ${args}`);
    const result = originalMethod.apply(this, args);
    console.log(`Method ${propertyName} returned: ${result}`);
    return result;
  };
}

class Calculator {
  @Log
  add(a: number, b: number): number {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3);  // আউটপুট হবে: Method add called with args: [2, 3] \n Method add returned: 5

এখানে:

  • @Log ডেকোরেটর add মেথডের উপরে প্রয়োগ করা হয়েছে, যা মেথড কলের আগ ও পর লগিং করবে।
  • Log ডেকোরেটরটি descriptor.value এর মাধ্যমে মেথডটির ডিফল্ট আচরণ পরিবর্তন করছে।

৬. Property Decorators

Property Decorators প্রপার্টির উপরে কার্যকর হয় এবং তার আচরণ পরিবর্তন করতে পারে।

উদাহরণ: Property Decorator

function MaxLength(max: number) {
  return function (target: any, propertyName: string) {
    let value: string;

    const getter = () => value;
    const setter = (newValue: string) => {
      if (newValue.length > max) {
        console.log(`${propertyName} is too long! Max length is ${max}`);
      } else {
        value = newValue;
      }
    };

    Object.defineProperty(target, propertyName, {
      get: getter,
      set: setter
    });
  };
}

class User {
  @MaxLength(10)
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

const user = new User("John Doe");
user.name = "A very long name";  // আউটপুট: name is too long! Max length is 10

এখানে:

  • MaxLength ডেকোরেটরটি name প্রপার্টির উপর প্রয়োগ করা হয়েছে, যাতে প্রপার্টির মান ১০টি অক্ষরের বেশি হলে একটি বার্তা প্রদর্শিত হবে।

৭. Parameter Decorators

Parameter Decorators প্যারামিটারগুলোর উপর প্রয়োগ হয় এবং প্যারামিটারের টাইপ বা মান নিয়ন্ত্রণ করতে পারে।

উদাহরণ: Parameter Decorator

function LogParameter(target: any, methodName: string, parameterIndex: number) {
  console.log(`Method ${methodName} has a parameter at index ${parameterIndex}`);
}

class User {
  greet(@LogParameter message: string) {
    console.log(`Hello, ${message}`);
  }
}

const user = new User();
user.greet("Alice");  // আউটপুট: Method greet has a parameter at index 0

এখানে:

  • LogParameter ডেকোরেটরটি greet মেথডের প্যারামিটার message এর উপর অ্যাপ্লাই করা হয়েছে।

৮. Decorator ব্যবহার এবং সীমাবদ্ধতা

TypeScript এ ডেকোরেটরগুলির কিছু সীমাবদ্ধতা রয়েছে:

  • Decorator ব্যবহার experimental (অর্থাৎ experimentalDecorators অপশন চালু করতে হয়)।
  • Functionality limitations: কিছু পরিস্থিতিতে ডেকোরেটর প্রপার্টির বা মেথডের আচরণ পরিবর্তন করতে পারে, কিন্তু সরাসরি তাদের মান পরিবর্তন করা কঠিন হতে পারে।

সারাংশ

TypeScript এর decorators একটি শক্তিশালী ফিচার যা ক্লাস, মেথড, প্রপার্টি বা প্যারামিটারগুলির ওপর অতিরিক্ত কার্যকারিতা যোগ করতে ব্যবহৃত হয়। এটি ক্লাসের প্রোপার্টি বা মেথডের আচরণে ডাইনামিক পরিবর্তন ঘটানোর জন্য অনেক সুবিধা প্রদান করে। তবে, এটি একটি experimental ফিচার হওয়ায়, এর ব্যবহার করার আগে কিছু কনফিগারেশন এবং সাবধানতা অবলম্বন করা প্রয়োজন।

Content added By
Promotion

Are you sure to start over?

Loading...