<skill_overview> Write idiomatic, type-safe TypeScript with consistent naming and strictness
Writing new TypeScript code Reviewing naming and style Designing types or public APIs Configuring tsconfig strictness
TypeScript Coding Guidelines TSConfig Strict Option TypeScript Handbook - Narrowing
</skill_overview> <naming_conventions>
<applies_to>Types, interfaces, classes, enums, enum members</applies_to>
type UserProfile = { id: string; email: string }; interface HttpClient { request(url: string): Promise<Response>; } class OrderService { } enum OrderStatus { Pending, Completed }
<applies_to>Functions, methods, variables, parameters, properties</applies_to>
function calculateTotal(items: Item[]) { /* ... */ } const retryCount = 3;
<applies_to>Constants and literal configuration</applies_to>
const MAX_RETRY_COUNT = 3;
<applies_to>Interfaces</applies_to> Do not prefix interfaces with "I"
interface UserRepository { } interface IUserRepository { }
<applies_to>File names</applies_to> Use kebab-case for file names
user-profile.ts UserProfile.ts
</naming_conventions> <tsconfig_strictness> Enable "strict": true for all new code <recommended_options> strictNullChecks noImplicitAny noUncheckedIndexedAccess exactOptionalPropertyTypes useUnknownInCatchVariables </recommended_options>
{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, "useUnknownInCatchVariables": true } }
</tsconfig_strictness> <type_system_best_practices> Prefer "unknown" over "any" and narrow explicitly Use discriminated unions for variant data Write type guards for runtime checks Use "never" for exhaustive checks in switches
function parseJson(input: string): unknown { return JSON.parse(input); }
const value = parseJson("{"id":1}"); if (typeof value === "object" && value !== null && "id" in value) { // value is now narrowed }
type Shape = | { kind: "circle"; radius: number } | { kind: "square"; size: number };
function area(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "square": return shape.size * shape.size; default: { const _exhaustive: never = shape; return _exhaustive; } } }
function isError(value: unknown): value is Error { return value instanceof Error; }
</type_system_best_practices>
Prefer const and readonly for shared data Use ReadonlyArray and readonly properties for inputs Use "as const" for literal inference
const roles = ["admin", "user"] as const; type Role = typeof roles[number];
function setRole(userId: string, role: Role, flags: ReadonlyArray<string>) { // flags cannot be mutated here }
<module_boundaries>
Export explicit, stable APIs; keep helpers private Prefer named exports over default for consistency Avoid barrel files that hide dependencies in large codebases
</module_boundaries> <anti_patterns> Using "any" as a shortcut Overusing optional properties instead of unions Mixing null and undefined without clear semantics </anti_patterns>