ডাইনামিক অবজেক্ট ট্রান্সফরমেশন এবং ফ্লেক্সিবল প্রোপার্টি মডিফিকেশনের জন্য টাইপস্ক্রিপ্ট ম্যাপড টাইপের ক্ষমতা আনলক করুন, যা বিশ্বব্যাপী ডেভেলপারদের জন্য কোড রিইউজেবিলিটি এবং টাইপ সুরক্ষা বৃদ্ধি করে।
টাইপস্ক্রিপ্ট ম্যাপড টাইপ: অবজেক্ট ট্রান্সফরমেশন এবং প্রোপার্টি মডিফিকেশন-এ দক্ষতা অর্জন
সফটওয়্যার ডেভেলপমেন্টের সর্বদা পরিবর্তনশীল ল্যান্ডস্কেপে, রক্ষণাবেক্ষণযোগ্য, স্কেলেবল এবং নির্ভরযোগ্য অ্যাপ্লিকেশন তৈরির জন্য শক্তিশালী টাইপ সিস্টেমগুলি অত্যন্ত গুরুত্বপূর্ণ। টাইপস্ক্রিপ্ট, এর শক্তিশালী টাইপ অনুমান এবং উন্নত বৈশিষ্ট্যগুলির সাথে, বিশ্বব্যাপী ডেভেলপারদের জন্য একটি অপরিহার্য সরঞ্জাম হয়ে উঠেছে। এর সবচেয়ে শক্তিশালী ক্ষমতাগুলির মধ্যে ম্যাপড টাইপগুলি অন্যতম, এটি একটি অত্যাধুনিক প্রক্রিয়া যা আমাদের বিদ্যমান অবজেক্ট টাইপগুলিকে নতুনগুলিতে রূপান্তরিত করতে দেয়। এই ব্লগ পোস্টটি টাইপস্ক্রিপ্ট ম্যাপড টাইপগুলির জগতে গভীরভাবে প্রবেশ করবে, তাদের মৌলিক ধারণা, বাস্তব অ্যাপ্লিকেশন এবং কীভাবে তারা ডেভেলপারদের অবজেক্ট ট্রান্সফরমেশন এবং প্রোপার্টি মডিফিকেশনগুলি সুন্দরভাবে পরিচালনা করতে সক্ষম করে তা অনুসন্ধান করবে।
ম্যাপড টাইপগুলির মূল ধারণা বোঝা
এর মূল অংশে, একটি ম্যাপড টাইপ হল একটি বিদ্যমান টাইপের বৈশিষ্ট্যগুলির উপর পুনরাবৃত্তি করে নতুন টাইপ তৈরি করার একটি উপায়। এটিকে টাইপগুলির জন্য একটি লুপ হিসাবে ভাবুন। মূল টাইপের প্রতিটি বৈশিষ্ট্যের জন্য, আপনি এর কী, এর মান বা উভয়ের উপর একটি রূপান্তর প্রয়োগ করতে পারেন। এটি ম্যানুয়াল পুনরাবৃত্তি ছাড়াই বিদ্যমানগুলির উপর ভিত্তি করে নতুন টাইপ সংজ্ঞা তৈরি করার জন্য বিস্তৃত সুযোগ উন্মুক্ত করে।
একটি ম্যাপড টাইপের জন্য মৌলিক সিনট্যাক্সে একটি { [P in K]: T } গঠন জড়িত, যেখানে:
P: পুনরাবৃত্তি করা বৈশিষ্ট্যের নাম উপস্থাপন করে।in K: এটি গুরুত্বপূর্ণ অংশ, যা নির্দেশ করে যেPটাইপK(যা সাধারণত স্ট্রিং লিটারেলের একটি ইউনিয়ন, অথবা একটি keyof টাইপ) থেকে প্রতিটি কী গ্রহণ করবে।T: নতুন টাইপে বৈশিষ্ট্যPএর মানের প্রকার নির্ধারণ করে।
আসুন একটি সাধারণ চিত্র দিয়ে শুরু করি। কল্পনা করুন আপনার কাছে ব্যবহারকারীর ডেটা উপস্থাপনকারী একটি অবজেক্ট রয়েছে এবং আপনি একটি নতুন টাইপ তৈরি করতে চান যেখানে সমস্ত বৈশিষ্ট্য ঐচ্ছিক। এটি একটি সাধারণ পরিস্থিতি, উদাহরণস্বরূপ, কনফিগারেশন অবজেক্ট তৈরি করার সময় বা আংশিক আপডেটগুলি বাস্তবায়ন করার সময়।
উদাহরণ 1: সমস্ত বৈশিষ্ট্যকে ঐচ্ছিক করা
এই বেস টাইপটি বিবেচনা করুন:
type User = {
id: number;
name: string;
email: string;
isActive: boolean;
};
আমরা একটি নতুন টাইপ, OptionalUser, তৈরি করতে পারি, যেখানে এই সমস্ত বৈশিষ্ট্য একটি ম্যাপড টাইপ ব্যবহার করে ঐচ্ছিক:
type OptionalUser = {
[P in keyof User]?: User[P];
};
আসুন এটি ভেঙে ফেলি:
keyof User: এটিUserটাইপের কীগুলির একটি ইউনিয়ন তৈরি করে (যেমন,'id' | 'name' | 'email' | 'isActive')।P in keyof User: এটি ইউনিয়নের প্রতিটি কী এর উপর পুনরাবৃত্তি করে।?: এটি এমন একটি মডিফায়ার যা বৈশিষ্ট্যটিকে ঐচ্ছিক করে তোলে।User[P]: এটি একটি লুকআপ টাইপ। প্রতিটি কীPএর জন্য, এটি মূলUserটাইপ থেকে সংশ্লিষ্ট মানের প্রকারটি পুনরুদ্ধার করে।
ফলস্বরূপ OptionalUser টাইপটি দেখতে এইরকম হবে:
{
id?: number;
name?: string;
email?: string;
isActive?: boolean;
}
এটি অবিশ্বাস্যভাবে শক্তিশালী। একটি ? দিয়ে প্রতিটি বৈশিষ্ট্য ম্যানুয়ালি পুনরায় সংজ্ঞায়িত করার পরিবর্তে, আমরা গতিশীলভাবে টাইপ তৈরি করেছি। এই নীতিটি আরও অনেক ইউটিলিটি টাইপ তৈরি করতে প্রসারিত করা যেতে পারে।
ম্যাপড টাইপগুলিতে সাধারণ প্রোপার্টি মডিফায়ার
ম্যাপড টাইপগুলি কেবল বৈশিষ্ট্যগুলিকে ঐচ্ছিক করার বিষয়ে নয়। তারা আপনাকে ফলস্বরূপ টাইপের বৈশিষ্ট্যগুলিতে বিভিন্ন মডিফায়ার প্রয়োগ করার অনুমতি দেয়। সর্বাধিক সাধারণগুলির মধ্যে রয়েছে:
- ঐচ্ছিকতা:
?মডিফায়ার যোগ করা বা সরানো। - রিডঅনলি:
readonlyমডিফায়ার যোগ করা বা সরানো। - নালযোগ্যতা/নন-নালযোগ্যতা:
| nullঅথবা| undefinedযোগ করা বা সরানো।
উদাহরণ 2: একটি টাইপের রিডঅনলি সংস্করণ তৈরি করা
বৈশিষ্ট্যগুলিকে ঐচ্ছিক করার মতো, আমরা একটি ReadonlyUser টাইপ তৈরি করতে পারি:
type ReadonlyUser = {
readonly [P in keyof User]: User[P];
};
এটি তৈরি করবে:
{
readonly id: number;
readonly name: string;
readonly email: string;
readonly isActive: boolean;
}
এটি নিশ্চিত করার জন্য অত্যন্ত দরকারী যে একবার তৈরি হয়ে গেলে কিছু ডেটা স্ট্রাকচার পরিবর্তন করা যায় না, যা শক্তিশালী, অনুমানযোগ্য সিস্টেম তৈরির জন্য একটি মৌলিক নীতি, বিশেষত সমবর্তী পরিবেশে বা অনেক আন্তর্জাতিক উন্নয়ন দল দ্বারা গৃহীত কার্যকরী প্রোগ্রামিং প্যারাডাইমগুলিতে জনপ্রিয় অপরিবর্তনীয় ডেটা প্যাটার্নগুলির সাথে কাজ করার সময়।
উদাহরণ 3: ঐচ্ছিকতা এবং রিডঅনলি একত্রিত করা
আমরা মডিফায়ারগুলিকে একত্রিত করতে পারি। উদাহরণস্বরূপ, একটি টাইপ যেখানে বৈশিষ্ট্যগুলি ঐচ্ছিক এবং রিডঅনলি উভয়ই:
type OptionalReadonlyUser = {
readonly [P in keyof User]?: User[P];
};
এর ফলে:
{
readonly id?: number;
readonly name?: string;
readonly email?: string;
readonly isActive?: boolean;
}
ম্যাপড টাইপগুলির সাথে মডিফায়ারগুলি সরানো
আপনি যদি কোনও মডিফায়ার সরাতে চান? টাইপস্ক্রিপ্ট ম্যাপড টাইপগুলির মধ্যে -? এবং -readonly সিনট্যাক্স ব্যবহার করে এটির অনুমতি দেয়। বিদ্যমান ইউটিলিটি টাইপ বা জটিল টাইপ কম্পোজিশনের সাথে কাজ করার সময় এটি বিশেষভাবে শক্তিশালী।
ধরুন আপনার কাছে একটি Partial<T> টাইপ রয়েছে (যা বিল্ট-ইন এবং সমস্ত বৈশিষ্ট্যকে ঐচ্ছিক করে তোলে), এবং আপনি এমন একটি টাইপ তৈরি করতে চান যা Partial<T> এর মতোই তবে সমস্ত বৈশিষ্ট্য আবার বাধ্যতামূলক করা হয়েছে।
type Mandatory<T> = {
-?: T extends object ? T[keyof T] : never;
};
type FullyPopulatedUser = Mandatory<Partial<User>>;
এটি স্বজ্ঞাত মনে হয়। আসুন এটি বিশ্লেষণ করি:
Partial<User> আমাদের OptionalUser এর সমতুল্য। এখন, আমরা এর বৈশিষ্ট্যগুলিকে বাধ্যতামূলক করতে চাই। সিনট্যাক্স -? ঐচ্ছিক মডিফায়ারটি সরিয়ে দেয়।
Partial এর উপর নির্ভর না করে এটি অর্জনের আরও সরাসরি উপায় হ'ল কেবল মূল টাইপটি নেওয়া এবং যদি এটি ঐচ্ছিক হত তবে এটিকে বাধ্যতামূলক করা:
type MakeMandatory<T> = {
-?: T;
};
type MandatoryUser = MakeMandatory<OptionalUser>;
এটি সঠিকভাবে OptionalUser কে মূল User টাইপ স্ট্রাকচারে ফিরিয়ে আনবে (সমস্ত বৈশিষ্ট্য উপস্থিত এবং প্রয়োজনীয়)।
একইভাবে, readonly মডিফায়ারটি সরাতে:
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
type MutableUser = Mutable<ReadonlyUser>;
MutableUser মূল User টাইপের সমতুল্য হবে, তবে এর বৈশিষ্ট্যগুলি রিডঅনলি হবে না।
নালযোগ্যতা এবং অসংজ্ঞায়িততা
আপনি নালযোগ্যতাও নিয়ন্ত্রণ করতে পারেন। উদাহরণস্বরূপ, সমস্ত বৈশিষ্ট্য অবশ্যই নন-নালযোগ্য তা নিশ্চিত করতে:
type NonNullableValues<T> = {
[P in keyof T]-?: NonNullable<T[P]>;
};
interface MaybeNull {
name: string | null;
age: number | undefined;
}
type DefiniteValues = NonNullableValues<MaybeNull>;
// type DefiniteValues = {
// name: string;
// age: number;
// }
এখানে, -? নিশ্চিত করে যে বৈশিষ্ট্যগুলি ঐচ্ছিক নয়, এবং NonNullable<T[P]> মানের প্রকার থেকে null এবং undefined সরিয়ে দেয়।
বৈশিষ্ট্য কীগুলি রূপান্তর করা
ম্যাপড টাইপগুলি অবিশ্বাস্যভাবে বহুমুখী, এবং তারা কেবল মান বা মডিফায়ারগুলি পরিবর্তন করার জন্য থামে না। আপনি কোনও অবজেক্ট টাইপের কীগুলি-ও রূপান্তর করতে পারেন। জটিল পরিস্থিতিতে ম্যাপড টাইপগুলি সত্যই উজ্জ্বল হয়।
উদাহরণ 4: বৈশিষ্ট্য কীগুলি উপসর্গ করা
ধরুন আপনি একটি নতুন টাইপ তৈরি করতে চান যেখানে একটি বিদ্যমান টাইপের সমস্ত বৈশিষ্ট্যের একটি নির্দিষ্ট উপসর্গ রয়েছে। এটি নেমস্পেসিংয়ের জন্য বা ডেটা স্ট্রাকচারের বিভিন্নতা তৈরি করার জন্য দরকারী হতে পারে।
type Prefixed<T, Prefix extends string> = {
[P in keyof T as `${Prefix}${Capitalize<string & P>}`]: T[P];
};
type OriginalConfig = {
timeout: number;
retries: number;
};
type PrefixedConfig = Prefixed<OriginalConfig, 'app'>;
// type PrefixedConfig = {
// appTimeout: number;
// appRetries: number;
// }
আসুন কী রূপান্তরটি বিশ্লেষণ করি:
P in keyof T: এখনও মূল কীগুলির উপর পুনরাবৃত্তি করে।as `${Prefix}${Capitalize<string & P>}`: এটি কী পুনরায় ম্যাপিং ক্লজ।`${Prefix}${...}`: এটি প্রদত্তPrefixকে রূপান্তরিত বৈশিষ্ট্যের নামের সাথে সংযুক্ত করে নতুন কী নাম তৈরি করতে টেম্পলেট লিটারেল টাইপ ব্যবহার করে।Capitalize<string & P>: এটি নিশ্চিত করার জন্য একটি সাধারণ প্যাটার্ন যে বৈশিষ্ট্যের নামPএকটি স্ট্রিং হিসাবে বিবেচিত হয় এবং তারপরে ক্যাপিটালাইজড হয়। আমরাstring & Pব্যবহার করেPকেstringএর সাথে ছেদ করি, নিশ্চিত করে যে টাইপস্ক্রিপ্ট এটিকে একটি স্ট্রিং টাইপ হিসাবে বিবেচনা করে, যাCapitalizeএর জন্য প্রয়োজনীয়।
এই উদাহরণটি দেখায় যে আপনি কীভাবে বিদ্যমানগুলির উপর ভিত্তি করে গতিশীলভাবে বৈশিষ্ট্যগুলির নাম পরিবর্তন করতে পারেন, এটি কোনও অ্যাপ্লিকেশনটির বিভিন্ন স্তরের মধ্যে সামঞ্জস্য বজায় রাখার জন্য বা নির্দিষ্ট নামকরণের নিয়মাবলীযুক্ত বাহ্যিক সিস্টেমগুলির সাথে একত্রিত হওয়ার সময় একটি শক্তিশালী কৌশল।
উদাহরণ 5: বৈশিষ্ট্যগুলি ফিল্টার করা
আপনি যদি কেবল এমন বৈশিষ্ট্যগুলি অন্তর্ভুক্ত করতে চান যা একটি নির্দিষ্ট শর্ত পূরণ করে? এটি ম্যাপড টাইপগুলিকে কন্ডিশনাল টাইপ এবং কী পুনরায় ম্যাপিংয়ের জন্য as ক্লজের সাথে একত্রিত করে অর্জন করা যেতে পারে, প্রায়শই বৈশিষ্ট্যগুলি ফিল্টার করার জন্য।
type OnlyStrings<T> = {
[P in keyof T as T[P] extends string ? P : never]: T[P];
};
interface MixedData {
name: string;
age: number;
city: string;
isActive: boolean;
}
type StringOnlyData = OnlyStrings<MixedData>;
// type StringOnlyData = {
// name: string;
// city: string;
// }
এই ক্ষেত্রে:
T[P] extends string ? P : never: প্রতিটি বৈশিষ্ট্যPএর জন্য, আমরা পরীক্ষা করি যে এর মানের প্রকার (T[P])stringএর সাথে নির্ধারণযোগ্য কিনা।- যদি এটি একটি স্ট্রিং হয় তবে কী
Pরাখা হয়। - যদি এটি কোনও স্ট্রিং না হয় তবে এটি
neverএ ম্যাপ করা হয়। যখন কোনও কীneverএ ম্যাপ করা হয়, তখন এটি কার্যকরভাবে ফলস্বরূপ অবজেক্ট টাইপ থেকে সরানো হয়।
এই কৌশলটি বিস্তৃতগুলি থেকে আরও নির্দিষ্ট টাইপ তৈরি করার জন্য অমূল্য, উদাহরণস্বরূপ, কেবলমাত্র সেই কনফিগারেশন সেটিংস বের করা যা একটি নির্দিষ্ট ধরণের, বা তাদের প্রকৃতির দ্বারা ডেটা ক্ষেত্রগুলি পৃথক করা।
উদাহরণ 6: কীগুলিকে একটি আলাদা আকারে রূপান্তর করা
আপনি কীগুলিকে সম্পূর্ণ ভিন্ন ধরণের কীগুলিতে রূপান্তর করতে পারেন, উদাহরণস্বরূপ, স্ট্রিং কীগুলিকে সংখ্যাগুলিতে পরিণত করা বা এর বিপরীতে, যদিও এটি সরাসরি অবজেক্ট ম্যানিপুলেশনের জন্য কম সাধারণ এবং আরও উন্নত টাইপ-লেভেল প্রোগ্রামিংয়ের জন্য।
স্ট্রিং কীগুলিকে স্ট্রিং লিটারেলের ইউনিয়নে পরিণত করার কথা বিবেচনা করুন এবং তারপরে এটিকে একটি নতুন টাইপের ভিত্তি হিসাবে ব্যবহার করুন। যদিও এই নির্দিষ্ট উপায়ে ম্যাপড টাইপের ভিতরে কোনও অবজেক্টের কীগুলি সরাসরি রূপান্তর করা নয়, এটি দেখায় যে কীভাবে কীগুলি ম্যানিপুলেট করা যায়।
আরও সরাসরি কী রূপান্তরকরণের উদাহরণ হ'ল কীগুলিকে তাদের আপারকেস সংস্করণে ম্যাপ করা:
type UppercaseKeys<T> = {
[P in keyof T as Uppercase<string & P>]: T[P];
};
type LowercaseData = {
firstName: string;
lastName: string;
};
type UppercaseData = UppercaseKeys<LowercaseData>;
// type UppercaseData = {
// FIRSTNAME: string;
// LASTNAME: string;
// }
এটি প্রতিটি কী P কে তার আপারকেস সমতুল্যে রূপান্তর করতে as ক্লজ ব্যবহার করে।
বাস্তব অ্যাপ্লিকেশন এবং বাস্তব বিশ্বের পরিস্থিতি
ম্যাপড টাইপগুলি কেবল তাত্ত্বিক গঠন নয়; তাদের বিভিন্ন উন্নয়ন ডোমেনগুলিতে উল্লেখযোগ্য বাস্তব প্রয়োগ রয়েছে। এখানে কয়েকটি সাধারণ পরিস্থিতি রয়েছে যেখানে তারা অমূল্য:
1. পুনরায় ব্যবহারযোগ্য ইউটিলিটি টাইপ তৈরি করা
অনেক সাধারণ টাইপ রূপান্তরকে পুনরায় ব্যবহারযোগ্য ইউটিলিটি টাইপে আবদ্ধ করা যেতে পারে। টাইপস্ক্রিপ্টের স্ট্যান্ডার্ড লাইব্রেরি ইতিমধ্যে Partial<T>, Readonly<T>, Record<K, T>, এবং Pick<T, K> এর মতো দুর্দান্ত উদাহরণ সরবরাহ করে। আপনার বিকাশের কর্মপ্রবাহকে সুগম করতে আপনি ম্যাপড টাইপগুলি ব্যবহার করে নিজের কাস্টম ইউটিলিটি টাইপগুলি সংজ্ঞায়িত করতে পারেন।
উদাহরণস্বরূপ, একটি টাইপ যা সমস্ত বৈশিষ্ট্যকে এমন ফাংশনে ম্যাপ করে যা মূল মান গ্রহণ করে এবং একটি নতুন মান প্রদান করে:
type Mappers<T> = {
[P in keyof T]: (value: T[P]) => T[P];
};
interface ProductInfo {
name: string;
price: number;
}
type ProductMappers = Mappers<ProductInfo>;
// type ProductMappers = {
// name: (value: string) => string;
// price: (value: number) => number;
// }
2. ডায়নামিক ফর্ম হ্যান্ডলিং এবং বৈধতা
ফ্রন্টএন্ড ডেভেলপমেন্টে, বিশেষত রিয়্যাক্ট বা অ্যাঙ্গুলারের মতো ফ্রেমওয়ার্কগুলির সাথে (যদিও এখানে উদাহরণগুলি খাঁটি টাইপস্ক্রিপ্ট), ফর্মগুলি এবং তাদের বৈধতা রাজ্যগুলি পরিচালনা করা একটি সাধারণ কাজ। ম্যাপড টাইপগুলি প্রতিটি ফর্ম ক্ষেত্রের বৈধতা স্থিতি পরিচালনা করতে সহায়তা করতে পারে।
এমন একটি ফর্ম বিবেচনা করুন যেখানে ক্ষেত্রগুলি 'pristine', 'touched', 'valid' বা 'invalid' হতে পারে।
type FormFieldState = 'pristine' | 'touched' | 'dirty' | 'valid' | 'invalid';
type FormState<T> = {
[P in keyof T]: FormFieldState;
};
interface UserForm {
username: string;
email: string;
password: string;
}
type UserFormState = FormState<UserForm>;
// type UserFormState = {
// username: FormFieldState;
// email: FormFieldState;
// password: FormFieldState;
// }
এটি আপনাকে এমন একটি টাইপ তৈরি করতে দেয় যা আপনার ফর্মের ডেটা স্ট্রাকচারকে প্রতিফলিত করে তবে পরিবর্তে প্রতিটি ক্ষেত্রের স্থিতি ট্র্যাক করে, আপনার ফর্ম পরিচালনা লজিকের জন্য ধারাবাহিকতা এবং টাইপ সুরক্ষা নিশ্চিত করে। এটি বিশেষত আন্তর্জাতিক প্রকল্পগুলির জন্য উপকারী যেখানে বিভিন্ন UI/UX প্রয়োজনীয়তা জটিল ফর্ম রাজ্যগুলির দিকে পরিচালিত করতে পারে।
3. API প্রতিক্রিয়া রূপান্তর
API এর সাথে কাজ করার সময়, প্রতিক্রিয়ার ডেটা সর্বদা আপনার অভ্যন্তরীণ ডোমেন মডেলগুলির সাথে পুরোপুরি মেলে না। ম্যাপড টাইপগুলি API প্রতিক্রিয়াগুলিকে পছন্দসই আকারে রূপান্তর করতে সহায়তা করতে পারে।
এমন একটি API প্রতিক্রিয়ার কথা ভাবুন যা কীগুলির জন্য snake_case ব্যবহার করে, তবে আপনার অ্যাপ্লিকেশনটি camelCase পছন্দ করে:
// Assume this is the incoming API response type
type ApiUserData = {
user_id: number;
first_name: string;
last_name: string;
};
// Helper to convert snake_case to camelCase for keys
type ToCamelCase<S extends string>: string = S extends `${infer T}_${infer U}`
? `${T}${Capitalize<U>}`
: S;
type CamelCasedKeys<T> = {
[P in keyof T as ToCamelCase<string & P>]: T[P];
};
type AppUserData = CamelCasedKeys<ApiUserData>;
// type AppUserData = {
// userId: number;
// firstName: string;
// lastName: string;
// }
এটি স্ট্রিং ম্যানিপুলেশনের জন্য একটি পুনরাবৃত্ত কন্ডিশনাল টাইপ ব্যবহার করে আরও একটি উন্নত উদাহরণ। মূল বিষয় হ'ল ম্যাপড টাইপগুলি, অন্যান্য উন্নত টাইপস্ক্রিপ্ট বৈশিষ্ট্যগুলির সাথে মিলিত হয়ে জটিল ডেটা রূপান্তরগুলিকে স্বয়ংক্রিয় করতে পারে, বিকাশের সময় সাশ্রয় করে এবং রানটাইম ত্রুটির ঝুঁকি হ্রাস করে। বিভিন্ন ব্যাকএন্ড পরিষেবাগুলির সাথে কাজ করা বিশ্বব্যাপী দলগুলির জন্য এটি অত্যন্ত গুরুত্বপূর্ণ।
4. enum-এর মতো স্ট্রাকচার বাড়ানো
টাইপস্ক্রিপ্টের enums থাকলেও, কখনও কখনও আপনি আরও বেশি নমনীয়তা চাইতে পারেন বা অবজেক্ট লিটারেলগুলি থেকে টাইপগুলি তৈরি করতে চাইতে পারেন যা enum হিসাবে কাজ করে।
const AppPermissions = {
READ: 'read',
WRITE: 'write',
DELETE: 'delete',
ADMIN: 'admin',
} as const;
type Permission = typeof AppPermissions[keyof typeof AppPermissions];
// type Permission = 'read' | 'write' | 'delete' | 'admin'
type UserPermissions = {
[P in Permission]?: boolean;
};
type RolePermissions = {
[P in Permission]: boolean;
};
const userPerms: UserPermissions = {
read: true,
};
const adminRole: RolePermissions = {
read: true,
write: true,
delete: true,
admin: true,
};
এখানে, আমরা প্রথমে সমস্ত সম্ভাব্য অনুমতির স্ট্রিংগুলির একটি ইউনিয়ন টাইপ তৈরি করি। তারপরে, আমরা এমন টাইপ তৈরি করতে ম্যাপড টাইপগুলি ব্যবহার করি যেখানে প্রতিটি অনুমতি একটি কী, যা আমাদের নির্দিষ্ট করতে দেয় যে কোনও ব্যবহারকারীর সেই অনুমতি রয়েছে কিনা (ঐচ্ছিক) বা কোনও ভূমিকা এটিকে বাধ্যতামূলক করে কিনা (প্রয়োজনীয়)। এই প্যাটার্নটি বিশ্বব্যাপী অনুমোদন সিস্টেমে সাধারণ।
চ্যালেঞ্জ এবং বিবেচনা
যদিও ম্যাপড টাইপগুলি অবিশ্বাস্যভাবে শক্তিশালী, তবে সম্ভাব্য জটিলতা সম্পর্কে সচেতন হওয়া গুরুত্বপূর্ণ:
- পঠনযোগ্যতা এবং জটিলতা: অতিরিক্ত জটিল ম্যাপড টাইপগুলি পড়া এবং বোঝা কঠিন হয়ে যেতে পারে, বিশেষত এই উন্নত বৈশিষ্ট্যগুলিতে নতুন ডেভেলপারদের জন্য। সর্বদা স্বচ্ছতার জন্য চেষ্টা করুন এবং মন্তব্য যুক্ত করা বা জটিল রূপান্তরগুলি ভেঙে দেওয়ার কথা বিবেচনা করুন।
- কর্মক্ষমতা জড়িত: যদিও টাইপস্ক্রিপ্টের টাইপ চেকিং সংকলন-সময়, তবে অত্যন্ত জটিল টাইপ ম্যানিপুলেশনগুলি, তাত্ত্বিকভাবে, সংকলনের সময়কে সামান্য বাড়িয়ে তুলতে পারে। বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য, এটি নগণ্য, তবে খুব বড় কোডবেস বা অত্যন্ত কর্মক্ষমতা-সমালোচনামূলক বিল্ড প্রক্রিয়াগুলির জন্য এটি মনে রাখার মতো একটি বিষয়।
- ডিবাগিং: যখন কোনও ম্যাপড টাইপ অপ্রত্যাশিত ফলাফল তৈরি করে, তখন ডিবাগিং কখনও কখনও চ্যালেঞ্জিং হতে পারে। টাইপগুলি কীভাবে সমাধান করা হচ্ছে তা বোঝার জন্য টাইপস্ক্রিপ্ট প্লেগ্রাউন্ড বা IDE এর টাইপ পরিদর্শন বৈশিষ্ট্যগুলি ব্যবহার করা অত্যন্ত গুরুত্বপূর্ণ।
keyofএবং লুকআপ টাইপগুলি বোঝা: ম্যাপড টাইপগুলির কার্যকর ব্যবহারkeyofএবং লুকআপ টাইপগুলির (T[P]) একটি দৃঢ় বোঝার উপর নির্ভর করে। নিশ্চিত করুন যে আপনার দলের এই মৌলিক ধারণাগুলির একটি ভাল ধারণা রয়েছে।
ম্যাপড টাইপগুলি ব্যবহারের জন্য সেরা অনুশীলন
তাদের চ্যালেঞ্জগুলি হ্রাস করার সময় ম্যাপড টাইপগুলির পুরো সম্ভাবনাকে কাজে লাগানোর জন্য, এই সেরা অনুশীলনগুলি বিবেচনা করুন:
- সহজ দিয়ে শুরু করুন: জটিল কী পুনরায় ম্যাপিং বা কন্ডিশনাল লজিকের দিকে যাওয়ার আগে বেসিক ঐচ্ছিকতা এবং রিডঅনলি রূপান্তর দিয়ে শুরু করুন।
- বিল্ট-ইন ইউটিলিটি টাইপগুলির সুবিধা নিন: টাইপস্ক্রিপ্টের বিল্ট-ইন ইউটিলিটি টাইপগুলির সাথে নিজেকে পরিচিত করুন যেমন
Partial,Readonly,Record,Pick,OmitএবংExclude। তারা প্রায়শই সাধারণ কাজের জন্য যথেষ্ট এবং ভালভাবে পরীক্ষিত এবং বোঝা যায়। - পুনরায় ব্যবহারযোগ্য জেনেরিক টাইপ তৈরি করুন: সাধারণ ম্যাপড টাইপ প্যাটার্নগুলিকে জেনেরিক ইউটিলিটি টাইপে আবদ্ধ করুন। এটি আপনার প্রকল্প জুড়ে এবং বিশ্বব্যাপী দলগুলির জন্য ধারাবাহিকতা প্রচার করে এবং বয়লারপ্লেট কোড হ্রাস করে।
- বর্ণনমূলক নাম ব্যবহার করুন: আপনার ম্যাপড টাইপ এবং জেনেরিক প্যারামিটারগুলির উদ্দেশ্য নির্দেশ করার জন্য স্পষ্টভাবে নামকরণ করুন (যেমন,
Optional<T>,DeepReadonly<T>,PrefixedKeys<T, Prefix>)। - পঠনযোগ্যতাকে অগ্রাধিকার দিন: যদি কোনও ম্যাপড টাইপ খুব জটিল হয়ে যায় তবে বিবেচনা করুন যে একই ফলাফল অর্জনের জন্য কোনও সরল উপায় আছে কিনা বা এটি যুক্ত জটিলতার মূল্যবান কিনা। কখনও কখনও, কিছুটা বেশি ভার্বোস তবে সুস্পষ্ট ধরণের সংজ্ঞা পছন্দনীয়।
- জটিল টাইপগুলি ডকুমেন্ট করুন: জটিল ম্যাপড টাইপগুলির জন্য, তাদের কার্যকারিতা ব্যাখ্যা করে JSDoc মন্তব্য যুক্ত করুন, বিশেষত যখন কোনও বিবিধ আন্তর্জাতিক দলের মধ্যে কোড ভাগ করে নেওয়া হয়।
- আপনার টাইপগুলি পরীক্ষা করুন: আপনার ম্যাপড টাইপগুলি প্রত্যাশার মতো আচরণ করে কিনা তা যাচাই করার জন্য টাইপ পরীক্ষা লিখুন বা উদাহরণ ব্যবহার করুন। জটিল রূপান্তরগুলির জন্য এটি বিশেষভাবে গুরুত্বপূর্ণ যেখানে সূক্ষ্ম বাগগুলি ধরা শক্ত হতে পারে।
উপসংহার
টাইপস্ক্রিপ্ট ম্যাপড টাইপগুলি উন্নত টাইপ ম্যানিপুলেশনের একটি ভিত্তি, যা ডেভেলপারদের অবজেক্ট টাইপগুলিকে রূপান্তর এবং অভিযোজিত করার জন্য অতুলনীয় ক্ষমতা সরবরাহ করে। আপনি বৈশিষ্ট্যগুলিকে ঐচ্ছিক, রিড-অনলি, তাদের নামকরণ বা জটিল শর্তগুলির ভিত্তিতে ফিল্টার করছেন কিনা, ম্যাপড টাইপগুলি আপনার ডেটা স্ট্রাকচারগুলি পরিচালনা করার জন্য একটি ঘোষণামূলক, টাইপ-সুরক্ষিত এবং অত্যন্ত অভিব্যক্তিপূর্ণ উপায় সরবরাহ করে।
এই কৌশলগুলিতে দক্ষতা অর্জনের মাধ্যমে, আপনি কোড পুনরায় ব্যবহারযোগ্যতা উল্লেখযোগ্যভাবে বাড়িয়ে তুলতে পারেন, টাইপ সুরক্ষা উন্নত করতে পারেন এবং আরও শক্তিশালী এবং রক্ষণাবেক্ষণযোগ্য অ্যাপ্লিকেশন তৈরি করতে পারেন। আপনার টাইপস্ক্রিপ্ট বিকাশের উন্নতি করতে এবং বিশ্বব্যাপী দর্শকদের জন্য উচ্চ-মানের সফ্টওয়্যার সমাধান তৈরিতে অবদান রাখতে ম্যাপড টাইপগুলির শক্তিকে আলিঙ্গন করুন। আপনি যখন বিভিন্ন অঞ্চলের ডেভেলপারদের সাথে সহযোগিতা করেন, তখন এই উন্নত টাইপ প্যাটার্নগুলি কোয়ালিটি এবং ধারাবাহিকতা নিশ্চিত করার জন্য একটি সাধারণ ভাষা হিসাবে কাজ করতে পারে, টাইপ সিস্টেমের কঠোরতার মাধ্যমে সম্ভাব্য যোগাযোগের ব্যবধানগুলি পূরণ করে।