Claude Code और TypeScript: तेज लेकिन सुरक्षित विकास के व्यावहारिक टिप्स
strict, Zod, Union, generics, satisfies और type tests से Claude Code TypeScript को भरोसेमंद बनाएं।
Claude Code TypeScript विकास को तेज कर सकता है, खासकर forms, API helpers और tests में। लेकिन अगर type boundary साफ नहीं है, तो कमजोर code भी तेजी से बनता है। Beginner के लिए सबसे सुरक्षित आदत है: feature मांगने से पहले type rules तय करना।
यहां strict का मतलब है कि TypeScript संदिग्ध code को आसानी से pass नहीं करता।
Domain types business rules को type के रूप में लिखते हैं।
Discriminated Union state के हिसाब से data shape अलग करती है, और runtime validation program चलते समय data की जांच करता है।
पहले type map दें
लंबे prompt से पहले छोटा map दें: compiler rules, domain types, external input, states और type tests। इससे Claude Code का diff review करना आसान होता है।
flowchart TD
A["Requirement"] --> B["tsconfig: strict rules"]
B --> C["Domain types: Plan और Account"]
C --> D["External data: unknown फिर validate"]
D --> E["State: discriminated unions"]
E --> F["Type tests: expectTypeOf / tsd"]
F --> G["Claude Code implementation और review"]
Official TypeScript references के लिए strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes, Narrowing, Generics, Utility Types और satisfies देखें।
Runtime validation के लिए Zod docs भी देखें।
Related articles: TypeScript Utility Types, TypeScript Generics, और Zod Validation।
strict tsconfig से शुरू करें
सिर्फ “TypeScript में बनाओ” न कहें। पहले compiler contract दें।
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts"]
}
Prompt में constraints भी लिखें।
यह repository strict TypeScript इस्तेमाल करती है।
any introduce न करें। External input को unknown मानें और Zod से validate करें।
Union को switch में handle करते समय never exhaustiveness check जोड़ें।
Implementation के बाद npx tsc --noEmit चलाएं।
noUncheckedIndexedAccess array और object पढ़ते समय undefined की possibility दिखाता है।
यह API field missing, empty list और translation missing जैसी problems जल्दी पकड़ता है।
Use case 1: SaaS plan को domain type बनाना
Domain types business rules को TypeScript में लिखते हैं। Plan, permission, billing state और publish state को UI से पहले model करें।
export type Plan = "free" | "pro" | "enterprise";
export type Account = {
id: string;
email: string;
plan: Plan;
seats: number;
trialEndsAt: string | null;
};
export type CreateAccountInput = {
email: string;
plan: Exclude<Plan, "enterprise">;
seats?: number;
};
export type UpdateAccountInput = Partial<
Pick<Account, "email" | "plan" | "seats" | "trialEndsAt">
>;
Exclude Union से कुछ members हटाता है।
Partial properties को optional बनाता है। Update API के लिए अच्छा है, लेकिन create input में गलती से required fields भी optional हो सकते हैं।
Use case 2: API data को unknown से validate करना
TypeScript types runtime पर नहीं रहते।
API, forms, cookies, localStorage, CSV और AI output गलत हो सकते हैं।
उन्हें unknown लें, validate करें, फिर typed value इस्तेमाल करें।
npm install zod
import { z } from "zod";
const AccountSchema = z.object({
id: z.string().min(1),
email: z.string().email(),
plan: z.enum(["free", "pro", "enterprise"]),
seats: z.number().int().positive(),
trialEndsAt: z.string().datetime().nullable()
});
type Account = z.infer<typeof AccountSchema>;
export function parseAccountResponse(json: unknown): Account {
return AccountSchema.parse(json);
}
unknown का मतलब है कि value अभी prove नहीं हुई।
any के उलट, यह validation से पहले property access रोकता है।
Use case 3: payment state को Union से बंद करना
Payment, upload, form submit और background jobs state machines हैं।
status: string बहुत ढीला है।
type PaymentResult =
| { status: "pending"; invoiceId: string }
| { status: "paid"; invoiceId: string; paidAt: string }
| { status: "failed"; invoiceId: string; reason: string };
export function renderPaymentMessage(result: PaymentResult): string {
switch (result.status) {
case "pending":
return `Invoice ${result.invoiceId} is waiting for payment.`;
case "paid":
return `Invoice ${result.invoiceId} was paid at ${result.paidAt}.`;
case "failed":
return `Invoice ${result.invoiceId} failed: ${result.reason}.`;
default: {
const exhaustive: never = result;
return exhaustive;
}
}
}
never branch TypeScript से सभी valid cases check करवाता है।
अगर बाद में refunded state जोड़ी गई और branch नहीं लिखा, compiler बताएगा।
Use case 4: generics और satisfies
Generics reusable helpers बनाते हैं और call site का exact type बचाते हैं।
export function groupBy<T, K extends PropertyKey>(
items: readonly T[],
getKey: (item: T) => K
): Partial<Record<K, T[]>> {
const grouped: Partial<Record<K, T[]>> = {};
for (const item of items) {
const key = getKey(item);
const bucket = grouped[key] ?? [];
bucket.push(item);
grouped[key] = bucket;
}
return grouped;
}
const accounts = [
{ id: "a1", plan: "free" },
{ id: "a2", plan: "pro" },
{ id: "a3", plan: "pro" }
] as const;
const byPlan = groupBy(accounts, (account) => account.plan);
const proAccounts = byPlan.pro ?? [];
console.log(proAccounts.map((account) => account.id));
Configuration objects में broad assertion की जगह satisfies बेहतर है।
type ApiRoute = {
method: "GET" | "POST" | "PATCH" | "DELETE";
path: `/${string}`;
auth: boolean;
};
const routes = {
listAccounts: { method: "GET", path: "/accounts", auth: true },
createAccount: { method: "POST", path: "/accounts", auth: true },
healthCheck: { method: "GET", path: "/health", auth: false }
} as const satisfies Record<string, ApiRoute>;
type RouteName = keyof typeof routes;
export function getRoute(name: RouteName) {
return routes[name];
}
Type-level tests जोड़ें
Important public types के लिए tests रखें।
npm install -D vitest tsd
import { expectTypeOf, test } from "vitest";
type CreateAccountInput = {
email: string;
plan: "free" | "pro";
seats?: number;
};
test("CreateAccountInput keeps the public API narrow", () => {
expectTypeOf<CreateAccountInput>().toMatchTypeOf<{
email: string;
plan: "free" | "pro";
seats?: number;
}>();
});
Practical use cases और pitfalls
| Use case | Type system क्या fix करता है | Claude Code क्या generate कर सकता है |
|---|---|---|
| SaaS billing | plan, invoice state, permissions | UI branches, forms, messages |
| Admin API screen | Zod schema, response type | fetch helpers, tables, loading state |
| Article CMS | slug, locale, publish state, hero image | MDX drafts, list pages, validation fixes |
| Contact form | input schema, result Union | UI, submit handler, Vitest tests |
| Pitfall | क्या खराब होता है | उपाय |
|---|---|---|
API response को any रखना | गलत JSON भी compile होता है | unknown और Zod |
status: string | impossible state आ सकती है | discriminated Union |
बहुत सारे as User | error छिपता है | schema, guards, satisfies |
create input में Partial<T> | required fields optional हो जाते हैं | create और update types अलग करें |
| type tests नहीं | public types चुपचाप wide होते हैं | expectTypeOf या tsd |
ClaudeCodeLab article workflow में Masa ने lang: string की वजह से गलत locale URL देखे।
Locale को fixed Union बनाने के बाद Claude Code की suggestions ज्यादा भरोसेमंद हुईं।
CLAUDE.md rules और CTA
## TypeScript rules
- Use strict TypeScript.
- Do not introduce `any`. Use `unknown` at external boundaries.
- Prefer discriminated unions for states.
- Prefer `satisfies` over broad type assertions.
- Derive API types from Zod schemas when runtime data is involved.
- Add Vitest or tsd style type checks for exported helper types.
- Run `npx tsc --noEmit` before reporting completion.
Solo projects के लिए products catalog में Claude Code templates और checklists मिलते हैं।
Teams के लिए Claude Code training and consulting strict migration, Zod boundaries, type tests और CLAUDE.md rules को real repository में लागू करने में मदद कर सकता है।
Tested result
मैंने इस workflow को छोटे TypeScript project में आजमाया: API responses को any से unknown plus Zod में बदला, फिर Claude Code से Union branches और expectTypeOf tests जुड़वाए।
Useful result यह था कि missing states और invalid property access code review से पहले मिल गए।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code permission safety ladder: access धीरे-धीरे बढ़ाएं
read-only से limited edits, proof commands और deploy checks तक permission बढ़ाने की सुरक्षित ladder.
Claude Code Small PR Proof Pack: छोटे PR को review-ready बनाना
Claude Code PR के लिए diff, checks, public URL, CTA path और rollback वाला practical proof pack.
Claude Code Review Gate Before Commit: diff, test, public URL और CTA जांच
Claude Code से commit से पहले review gate बनाएं: diff, build, public URL, Gumroad, consultation, tests और unrelated files।