پہلے میں اس خیال کو جان بوجھ کر زیادہ provocative انداز میں بیان کرتا تھا: Codex کے لیے TypeScript بہترین زبان ہے۔ اب میں اسے زیادہ درست انداز میں کہوں گا۔ جس قسم کی production frontend اور full-stack development میں کرتا ہوں، اس میں TypeScript وہ environment ہے جہاں Codex کو control، verify اور مناسب اعتماد کے ساتھ استعمال کرنا سب سے آسان لگتا ہے۔
اصل لفظ “TypeScript” نہیں بلکہ control ہے۔ AI coding agents ایسا code بنانے میں بہت اچھے ہیں جو بظاہر درست لگتا ہے۔ Production engineering زیادہ سخت ہے: code کو existing contracts ماننے، behavior محفوظ رکھنے، refactor برداشت کرنے اور غلط assumption پر جلد fail ہونے کی ضرورت ہے۔ Plain JavaScript کے مقابلے میں TypeScript ان constraints کا بہت بڑا حصہ machine-readable بنا دیتا ہے۔
Codex کو codebase سے حقیقت میں کیا چاہیے
اچھا prompt مدد کرتا ہے، مگر context کا صرف ایک ذریعہ ہے۔ Codebase خود task کو واضح کر سکتا ہے یا model کو guess کرنے پر مجبور کر سکتا ہے۔ عملی طور پر بہترین environment وہ ہے جہاں اہم assumptions واضح اور automatically checked ہوں۔
- Function signatures valid input اور output متعین کرتے ہیں۔
- Interfaces اور types domain objects کا shape واضح کرتے ہیں۔
- Unions اور enums valid states کو محدود کرتے ہیں۔
- Compiler edit کے فوراً بعد کئی غلط assumptions کو concrete errors میں بدل دیتا ہے۔
اگر contract ٹوٹتے ہی codebase خود feedback دے، تو AI agent کو پوری application perfect طور پر سمجھنے کی ضرورت نہیں۔ Feedback loop جتنا چھوٹا ہوگا، confident guessing کی جگہ اتنی کم ہوگی۔
Types صرف documentation نہیں، executable context ہیں
اچھا TypeScript انسان کو design intent بتاتا ہے۔ Automated workflow میں ایک اضافی فائدہ ہے: یہ documentation machine سے verify ہو سکتی ہے۔ مثال:
type PaymentResult =
| { ok: true; receiptId: string }
| { ok: false; code: "declined" | "timeout" };
function getReceiptId(result: PaymentResult) {
if (result.ok) return result.receiptId;
return result.receiptId;
// TypeScript: Property 'receiptId' does not exist
// on the failure branch.
}JavaScript میں یہی غلطی اس branch کے runtime پر چلنے تک reasonable لگ سکتی ہے۔ TypeScript merge سے پہلے assumption reject کر سکتا ہے۔ Codex کے لیے compiler error صرف editor کی red line نہیں بلکہ یہ واضح signal ہے کہ model نے کیا غلط سمجھا۔
اسی لیے میں Record<string, any> جیسے broad structure کے بجائے explicit domain types پسند کرتا ہوں۔ Type reality کو جتنا درست describe کرے، codebase developer اور AI دونوں کے لیے اتنا بہتر context بنتا ہے۔
Compiler غلطی کو feedback loop بناتا ہے
میں “Codex سے code مانگو اور پہلا جواب قبول کر لو” والے process پر اعتماد نہیں کرتا۔ Reliable workflow iterative ہے:
task → inspect → edit → typecheck → lint → test → review diffیہ sequence boring ہے اور یہی اس کی طاقت ہے۔ ہر meaningful change کے بعد environment جواب دیتا ہے۔ Type errors broken contracts پکڑتے ہیں، lint دوسری class کی problems، tests وہ behavior verify کرتے ہیں جو types express نہیں کر سکتے، اور final diff پھر بھی human review سے گزرتا ہے۔
Smart prompt پہلی کوشش بہتر کر سکتا ہے۔ Strong verification loop ہر کوشش بہتر کرتا ہے۔ Production میں یہی زیادہ اہم ہے۔
بڑے refactor میں TypeScript کی value زیادہ نظر آتی ہے
Small isolated edit تقریباً ہر coding assistant کے لیے آسان ہے۔ مشکل change وہ ہے جو درجنوں files میں پھیلتا ہے: domain field rename، API response change، component props سخت کرنا، union split یا پرانی abstraction replace کرنا۔
TypeScript میں breaking change affected assumptions کا map بناتا ہے۔ Compiler دکھاتا ہے کہ old contract کہاں اب بھی استعمال ہو رہا ہے۔ Codex اس list پر کام کر کے ہر pass کے بعد validation دوبارہ چلا سکتا ہے۔ اس سے refactor خود بخود correct نہیں ہوتا، مگر blast radius نظر آنے لگتا ہے۔
TypeScript کہاں نہیں بچاتا
TypeScript guardrail ہے، correctness proof نہیں۔
- غلط business logic: perfectly typed code پھر بھی غلط calculation کر سکتا ہے۔
- Runtime data: API، database، form یا third-party service compile-time assumptions سے مختلف data دے سکتے ہیں۔
- Missing product context: compiler نہیں جانتا کہ flow کیوں موجود ہے یا کون سا edge case user کے لیے اہم ہے۔
- Security اور architecture: valid types صحیح authorization، caching، database boundaries یا infrastructure کی guarantee نہیں دیتے۔
اس لیے runtime validation، tests، logging، observability اور review ضروری ہیں۔ Clean typecheck کا مطلب correct feature نہیں۔
AI-assisted changes کے لیے میرا workflow
- Goal narrow رکھتا ہوں۔ کیا بدلنا ہے، کیا نہیں، اور acceptance criteria کیا ہیں۔
- Edit سے پہلے Codex سے inspect کرواتا ہوں۔ Existing types، call sites، tests اور neighboring modules long prompt سے زیادہ useful ہو سکتے ہیں۔
- Smallest coherent change پسند کرتا ہوں۔ Focused diff unrelated rewrite سے آسان verify ہوتا ہے۔
- فوراً typecheck اور lint چلاتا ہوں۔ Structural errors change چھوٹا رہتے ہی سامنے آئیں۔
- Relevant tests چلاتا ہوں اور behavior بدلے تو test شامل کرتا ہوں۔ Types contracts validate کرتے ہیں، tests behavior۔
- Final diff خود review کرتا ہوں۔ Naming، architecture، duplication، edge cases اور original problem واقعی solve ہوا یا نہیں۔
JavaScript کب کافی ہے
یہ JavaScript کے خلاف argument نہیں۔ Small script، disposable prototype، simple automation یا کم shared state والے code میں TypeScript کی extra structure کی value کم ہو سکتی ہے۔ Strong tests اور clear conventions والا JavaScript project بھی AI کے لیے اچھا environment ہو سکتا ہے۔
میرا claim محدود ہے: codebase جتنا بڑا، long-lived اور collaborative ہو، machine-checkable constraints کی value اتنی بڑھتی ہے۔ اور اسی stage پر AI mistakes زیادہ مہنگی ہو جاتی ہیں۔
Codex کے ساتھ TypeScript پسند کرنے کی اصل وجہ
TypeScript Codex کو smarter نہیں بناتا۔ یہ environment کو bad assumptions کے لیے کم tolerant بناتا ہے۔
Production میں مجھے صرف creative agent نہیں چاہیے؛ ایسا agent چاہیے جو ایسے system میں کام کرے جو غلط ہونے پر مسلسل feedback دے۔ Types، compiler errors، lint، tests اور human review مل کر وہ system بناتے ہیں۔
اس لیے TypeScript + Codex کی بات language fandom نہیں۔ یہ fast, machine-checkable feedback کی بات ہے: کم ambiguity، چھوٹا blast radius، safer refactor اور verification سنجیدگی سے کرنے پر زیادہ reliable engineering speed۔