§

JSON নমুনা

Type inferrer প্রস্তুত করা হচ্ছে…
§

TypeScript interface

TypeScript

বাংলাদেশ ও পশ্চিমবঙ্গের TypeScript ডেভেলপাররা প্রায়ই তৃতীয় পক্ষের API বা webhook payload-এর ধরন নিয়ে সমস্যায় পড়েন। নেটওয়ার্ক প্যানেলে একটি real রেসপন্স ক্যাপচার করুন, এখানে পেস্ট করুন, endpoint-এর নামে root নামকরণ করুন, এবং আউটপুট প্রজেক্টের types ডিরেক্টরিতে কপি করুন। strict মোড তখন documentation-এ ভুলে যাওয়া mismatches ধরে ফেলে। inferrer সম্পূর্ণ ব্রাউজারে চলে, তাই staging API, signed webhook body, এবং অপ্রকাশিত endpoint-এর payload কোনো hosted সার্ভিসে পৌঁছায় না।

JSON-to-TypeScript inference কীভাবে কাজ করে

Inference হলো parsed JSON tree-এর উপর একটি একক pass। টুলটি প্রতিটি মান পড়ে, তার জন্য একটি TypeScript টাইপ বেছে নেয়, এবং তারপর প্রতিটি অবজেক্টের জন্য একটি interface লেখে।

  1. ব্রাউজারের native parser দিয়ে JSON নমুনা parse করুন এবং লাইন/কলাম hint সহ অবৈধ ইনপুট প্রত্যাখ্যান করুন।
  2. প্রতিটি মানের জন্য একটি TypeScript টাইপ sniff করুন — string, number, boolean, null, array, বা নেস্টেড অবজেক্ট।
  3. প্রতিটি নেস্টেড অবজেক্টকে তার parent property key থেকে নেওয়া interface নাম দিন (তাই user.address একটি Address interface হয়)।
  4. প্রতিটি অ্যারে জুড়ে আইটেমের ধরন merge করুন যাতে {id: 1} এবং {id: 2, label: "x"}-এর তালিকা সঠিক অপশনাল ফিল্ড সহ ইউনিয়ন তৈরি করে।
  5. আপনার অপশন প্রয়োগ করুন (interface বনাম type, readonly, optional-nullable) এবং dependency order-এ declaration emit করুন যাতে ফাইলটি forward reference ছাড়া compile হয়।

JSON থেকে TypeScript টাইপ কেন তৈরি করবেন?

  • রেসপন্স টাইপ লেখা থাকলে বেশিরভাগ shape bug compile টাইমে ধরা পড়ে। real payload থেকে interface অনুমান করা বেশিরভাগটা আপনার জন্য লেখে, এবং `strict` মোড doc-এ ভুলে যাওয়া ফিল্ড ধরে ফেলে।
  • Zod বা io-ts-এর মতো runtime validator-এর সাথে inferred interface যুক্ত করা একই shape-কে দুটো কাজ দেয়: development-এ editor autocomplete এবং production-এ অপ্রত্যাশিত কিছু এলে edge-এ 400।
  • TypeScript-এর language server শুধু সেই ফিল্ড দেখায় যা সে জানে। inferred interface import করার পরে, ডট টাইপ করার মুহূর্তেই autocomplete কাজ করে — রেসপন্সে আর `as any` cast বা repo জুড়ে বিরক্তিকর grep নেই।
  • আপনি যদি OpenAPI spec লিখতে চলেছেন, inferred interface হলো রেসপন্স schema-এর দ্রুত প্রথম খসড়া। হাতে লেখা উদাহরণ ও constraint এখনো লাগবে, কিন্তু property নাম ও টাইপ ইতিমধ্যে সঠিক।

সাধারণ প্রয়োগ

real payload থাকলে কিন্তু schema না থাকলে inference সবচেয়ে বেশি সাহায্য করে।

  • handler লেখার আগে Stripe, GitHub, বা Twilio থেকে তৃতীয় পক্ষের webhook payload টাইপ করা।
  • internal REST API-এর জন্য টাইপ bootstrap করা যাতে backend সম্পন্ন হওয়ার একই দিন frontend টিম কোড করা শুরু করতে পারে।
  • observed API রেসপন্স থেকে Zod, io-ts, বা Valibot schema-এর শুরুর পয়েন্ট তৈরি করা।

আউটপুট কেমন দেখায়?

একটি নমুনা JSON ডকুমেন্ট এবং একটি রুট নাম দিলে, generator একটি interface tree তৈরি করে, প্রতিটি নেস্টেড অবজেক্টের জন্য একটি। রুট নাম User সহ নিচের ইনপুটের জন্য:

রুট নাম User সহ {"id":1,"name":"Alice","tags":["a","b"],"address":{"city":"Paris"}} পেস্ট করুন এবং generator তৈরি করে:

export interface User {
  id: number;
  name: string;
  tags: string[];
  address: Address;
}

export interface Address {
  city: string;
}
লক্ষ্য করুন যে address তার নিজস্ব নামযুক্ত interface-এ উন্নীত হয়েছে — এটাই dependency-ordered আউটপুট। একই JSON type ডিক্লারেশন স্টাইলে export type User = {...} emit করবে; readonly toggle চালু থাকলে প্রতিটি property readonly modifier পাবে।

Generator অপশন

ডিক্লারেশন স্টাইল

interface (অবজেক্ট shape-এর জন্য মানক TypeScript idiom) বা type (পরে mapped type, conditional type, বা intersection দরকার হলে সুবিধাজনক) বেছে নিন। উভয়ই অভিন্ন runtime আচরণ তৈরি করে; পছন্দটি coding-style preference।

অপশনাল nullable ফিল্ড

নমুনা মান null হলে ফিল্ডের টাইপ T | null হয়। এই অপশন চালু করলে ? modifier-ও যোগ হয় যাতে ফিল্ড TypeScript-এর দিক থেকে অপশনাল হয় — যখন API null ফেরত না দিয়ে মাঝে মাঝে key-ই বাদ দেয় তখন দরকারী।

Readonly মডিফায়ার

প্রতিটি property declaration-এ readonly যোগ করে যাতে emitted interface একটি immutable ডেটা মডেলের সাথে মিলে। Redux state slice, frozen API রেসপন্স, বা যেখানে compiler দিয়ে আকস্মিক mutation flag করতে চান সেখানে সহজ।

এটি কি নেস্টেড অবজেক্ট ও অ্যারে সমর্থন করে?

হ্যাঁ। প্রতিটি নেস্টেড অবজেক্ট তার parent property key থেকে নেওয়া নামযুক্ত interface হয়, এবং অ্যারে তাদের বিষয়বস্তু থেকে আইটেমের ধরন অনুমান করে। অবজেক্টের অ্যারে প্রতিটি অবজেক্ট shape-এর জন্য একটি interface পায়, shape একমত না হলে ইউনিয়ন টাইপ সহ।

অপশনাল ফিল্ড কীভাবে অনুমান করা হয়?

"null-able ফিল্ড অপশনাল চিহ্নিত করুন" toggle চালু করুন এবং যে ফিল্ডের নমুনা মান null সেটি key-তে ? modifier এবং টাইপে | null পায়। toggle ছাড়া, ফিল্ড required থাকে এবং টাইপ শুধু T | null হয়।

এটি কি discriminated union সমর্থন করে?

অ্যারেতে mixed-shape আইটেম থাকলে বা ফিল্ডে একটি মান এবং null উভয়ই থাকলে basic ইউনিয়ন টাইপ আসে। সম্পূর্ণ discriminated-union inference (ট্যাগ হিসেবে type বা kind বেছে নেওয়া এবং variants বিভক্ত করা) একাধিক নমুনা প্রয়োজন — এটি planned কিন্তু আজকের build-এ নেই।

আমি কি একাধিক JSON নমুনা থেকে টাইপ অনুমান করতে পারি?

এখনো না — আজকের inferrer একটি নমুনা একসাথে পড়ে। যদি আপনার দুটো payload থাকে যা একটি interface শেয়ার করার কথা (যেমন একটি list endpoint এবং একটি single-item endpoint), ব্যবহারিক সমাধান হলো সেগুলো একটি অ্যারেতে merge করা, সেখান থেকে generate করা, এবং তারপর resulting union টাইপগুলো rename করা। Multi-sample inference roadmap-এ আছে কারণ এটাই একমাত্র উপায় যা দিয়ে বোঝা যায় কোন ফিল্ড একটি রেসপন্সে আছে এবং অন্যটিতে নেই।

payload পেস্ট করুন, রুটের নাম দিন, interface কপি করুন। পুরো pipeline আপনার ব্রাউজারে চলে, তাই অপ্রকাশিত API বা signed webhook body আপনার মেশিনেই থাকে।