TypeScript টিম তাদের 6.0 রিলিজের সাথে একটি নতুন কম্পাইলার ফ্ল্যাগ নিয়ে এসেছে – --noPropertyAccessFromIndexSignature। এটি চালু করলে, কম্পাইলার ইনডেক্স সিগনেচার (index signature) থেকে আসা প্রপার্টিগুলোতে ডট-নোটেশন (dot-notation) ব্যবহার করতে বাধা দেবে, ফলে ডেভেলপারদের ব্র্যাকেট নোটেশন (bracket notation) ব্যবহার করতে বাধ্য করা হবে এবং প্রোডাকশনে যাওয়ার আগেই কম্পাইল টাইমে সম্ভাব্য undefined ভ্যালুগুলো ধরা পড়বে।

কেন এই ফ্ল্যাগটি গুরুত্বপূর্ণ

JavaScript-এ অবজেক্টগুলো প্রায়ই ডিকশনারি হিসেবে কাজ করে, এবং TypeScript আপনাকে ইনডেক্স সিগনেচার ব্যবহার করে এই ধরনের স্ট্রাকচার টাইপ করতে দেয়, যেমন: Record<string, T>। ল্যাঙ্গুয়েজটি obj.key এবং obj["key"]-কে একই রকম হিসেবে বিবেচনা করে, তাই কী (key) শুধুমাত্র রানটাইমে জানা থাকলেও কম্পাইলার ধরে নেয় যে প্রপার্টিটি বিদ্যমান। এই নীরব অনুমানটিই অনেক ক্র্যাশের (crash) মূল কারণ: যে কোড obj.missingProp অ্যাক্সেস করে তা ঠিকঠাক কম্পাইল হয় এবং রানও করে, কিন্তু পরে এর ভ্যালু undefined হওয়ার কারণে এরর থ্রো করে।

ডট নোটেশন একটি অন্তর্নিহিত নিশ্চয়তা বহন করে – এটি পাঠক এবং টাইপ চেকারকে জানায় যে প্রপার্টিটি নিশ্চিতভাবেই উপস্থিত আছে। অন্যদিকে, ব্র্যাকেট নোটেশন অনিশ্চয়তা প্রকাশ করে – কী-টি অনুপস্থিত থাকতে পারে এবং ফলাফল undefined হতে পারে। --noPropertyAccessFromIndexSignature এই ভিজ্যুয়াল এবং সিম্যান্টিক পার্থক্যটি কার্যকর করে, যা রানটাইম এররগুলোকে কম্পাইল-টাইম ডায়াগনস্টিকসে রূপান্তরিত করে।

ফ্ল্যাগটি কীভাবে কাজ করে

যখন ফ্ল্যাগটি চালু করা হয়, তখন ইনডেক্স সিগনেচারের মাধ্যমে ডট নোটেশন ব্যবহার করে কোনো প্রপার্টি অ্যাক্সেস করার চেষ্টা করলে সেটি এরর হিসেবে চিহ্নিত হবে। কোডটি ব্র্যাকেট ব্যবহার করার জন্য পুনরায় লিখতে হবে:

// Before
const name = userData.name;          // OK even if "name" is not in the index

// After enabling the flag
const name = userData["name"];       // Error unless brackets are used

এরপর কম্পাইলার ব্র্যাকেট অ্যাক্সেসের জন্য আগে থেকেই ব্যবহৃত undefined-হ্যান্ডলিং নিয়মগুলো প্রয়োগ করে। যদি --noUncheckedIndexedAccess ফ্ল্যাগটিও চালু থাকে, তবে userData["name"]-এর টাইপ হয়ে যাবে T | undefined, যা ডেভেলপারকে অনুপস্থিত কেসটি (missing case) চেক করতে বাধ্য করবে।

ব্যবহারিক মাইগ্রেশন পদক্ষেপসমূহ

  1. ফ্ল্যাগটি চালু করুন tsconfig.json-এ:

    {
      "compilerOptions": {
        "noPropertyAccessFromIndexSignature": true
      }
    }
    
  2. টাইপ চেকার চালান। ইনডেক্স-সিগনেচার কী-গুলোর জন্য সমস্ত ডট-নোটেশন অ্যাক্সেস এরর হিসেবে প্রদর্শিত হবে।

  3. ডট সরিয়ে ব্র্যাকেট বসান। এই পরিবর্তনটি যান্ত্রিক; এটি রানটাইম পারফরম্যান্সে কোনো প্রভাব ফেলে না।

  4. ফলাফলস্বরূপ আসা undefined টাইপগুলো সমাধান করুন। প্রয়োজন অনুযায়ী nullish coalescing, optional chaining, অথবা স্পষ্ট চেক (explicit checks) যোগ করুন।

  5. সবচেয়ে শক্তিশালী সেফটি নেটের জন্য --noUncheckedIndexedAccess-এর সাথে এটি ব্যবহার করার কথা ভাবুন। একসাথে এগুলো নিশ্চিত করে যে ডিকশনারি-স্টাইল অ্যাক্সেসগুলোকে সম্ভাব্য অনুপস্থিত হিসেবে গণ্য করা হবে।

কখন এক্সপ্লিসিট প্রপার্টি (explicit properties) রাখা উচিত

যদি কোনো ফিল্ড একটি স্থিতিশীল API কন্ট্রাক্টের অংশ হয়, তবে ইনডেক্স সিগনেচারের ওপর নির্ভর না করে সেটিকে একটি এক্সপ্লিসিট প্রপার্টি হিসেবে ঘোষণা করুন। এক্সপ্লিসিট প্রপার্টিগুলো ডট নোটেশন ব্যবহার করতে দেয়, যা এই নিশ্চয়তা বজায় রাখে যে ফিল্ডটি সবসময় উপস্থিত থাকবে (যতক্ষণ না টাইপ সিস্টেমের মাধ্যমে তা যাচাই করা যাচ্ছে)। ইনডেক্স সিগনেচার শুধুমাত্র সত্যিকারের ডাইনামিক ডেটার জন্য রাখুন যেখানে কী (key) আগে থেকে জানা থাকে না।

পাল্টা যুক্তি: অতিরিক্ত ভারবোসিটি (verbosity)

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

পরবর্তীতে যা খেয়াল রাখতে হবে

এই ফ্ল্যাগটি TypeScript 6.0-এ টাইপ সেফটিকে আরও কঠোর করার একটি বৃহত্তর প্রচেষ্টার অংশ। ভবিষ্যতের রিলিজগুলোতে অবজেক্ট স্প্রেড (object spread), অপশনাল চেইনিং (optional chaining), বা ইনফার্ড any ব্যবহারের ক্ষেত্রে অতিরিক্ত চেক যুক্ত হতে পারে। TypeScript রোডম্যাপের ওপর নজর রাখা টিমগুলোকে সাহায্য করবে কখন ডেলিভারি শিডিউল ব্যাহত না করে পরবর্তী সেফটি ফিচারগুলো গ্রহণ করা উচিত।

সারকথা: --noPropertyAccessFromIndexSignature চালু করা কোডে “এই প্রপার্টিটি নিশ্চিত” এবং “এই প্রপার্টিটি অনুপস্থিত থাকতে পারে” — এই পার্থক্যটিকে স্পষ্ট করে তোলে, যা প্রোডাকশনে যাওয়ার আগেই এক শ্রেণির বাগ (bug) ধরে ফেলে। একটি নীরব রানটাইম ফেইলিউরকে কম্পাইল-টাইম এররে রূপান্তর করা একটি ছোট পরিবর্তন হলেও এটি নির্ভরযোগ্যতার ওপর ব্যাপক প্রভাব ফেলে।