TypeScript & JavaScript Development
Guiding Principles
- Type Safety: Leverage strict mode, avoid
any, use discriminated unions
- Explicit Over Implicit: Prefer explicit types for clarity and maintainability
- Modern Defaults: ESM, const/let, async/await, optional chaining
- Security First: Never use
eval, sanitize HTML, validate inputs
Quick Reference
| Aspect |
TypeScript |
JavaScript |
| Package Manager |
pnpm preferred |
pnpm preferred |
| Module System |
ES Modules |
ES Modules + // @ts-check |
| Linting |
eslint --max-warnings=0 |
eslint --max-warnings=0 |
| Formatting |
Prettier |
Prettier |
| Types |
Strict mode |
JSDoc types |
Critical Patterns
// 1. Use strict equality
if (value === 0) { } // ✅ GOOD
if (value == 0) { } // ❌ BAD
// 2. Handle Promise rejections
fetchData().catch(err => console.error(err)); // ✅ GOOD
// 3. Optional chaining and nullish coalescing
const name = user?.profile?.name ?? 'Guest'; // ✅ GOOD
// 4. Use Set/Map for lookups
const seen = new Set(); // ✅ GOOD (O(1))
const seen = []; // ❌ BAD (O(n))
// 5. Never use eval or new Function
eval(userInput); // ❌ NEVER DO THIS
// 6. Sanitize HTML
element.textContent = userInput; // ✅ GOOD
element.innerHTML = userInput; // ❌ BAD (XSS)
TypeScript Configuration
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Avoid any - Use Proper Types
// ❌ BAD - Loses all type safety
function processData(data: any): any {
return data.value;
}
// ✅ GOOD - Generic type
function processData<T>(data: T): T {
return data;
}
// ✅ GOOD - Unknown for truly unknown types
function processData(data: unknown): string {
if (typeof data === 'object' && data !== null && 'value' in data) {
return String((data as { value: unknown }).value);
}
throw new Error('Invalid data');
}
Discriminated Unions
type SuccessResponse = {
status: 'success';
data: { id: string; name: string };
};
type ErrorResponse = {
status: 'error';
error: { code: number; message: string };
};
type ApiResponse = SuccessResponse | ErrorResponse;
function handleResponse(response: ApiResponse): void {
if (response.status === 'success') {
console.log(response.data.id); // Type-safe
} else {
console.log(response.error.message); // Type-safe
}
}
Utility Types
interface User {
id: string;
name: string;
email: string;
password: string;
}
type UserUpdate = Partial<User>; // All optional
type UserCredentials = Pick<User, 'email' | 'password'>;
type UserPublic = Omit<User, 'password'>; // Exclude password
type RequiredUser = Required<User>; // All required
type ReadonlyUser = Readonly<User>; // Immutable
Async Patterns
// Parallel execution
const [users, products] = await Promise.all([
fetchUsers(),
fetchProducts()
]);
// Handle partial failures
const results = await Promise.allSettled([
fetchUsers(),
fetchProducts()
]);
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log(result.value);
} else {
console.error(result.reason);
}
});
Security Rules (Mandatory)
- Never use
eval, new Function, or unsanitized innerHTML
- Use
textContent for DOM insertion
- Validate and sanitize all external inputs
- Do not log secrets/tokens/PII
- Use parameterized queries; no string-built queries
- Enforce HTTPS; secure cookies (HttpOnly, SameSite)
Naming Conventions
| Type |
Convention |
Example |
| Functions/Variables |
camelCase |
fetchUserData |
| Classes/Interfaces |
PascalCase |
UserService |
| Constants |
UPPER_SNAKE_CASE |
MAX_RETRIES |
| Types |
PascalCase |
ApiResponse |
Detailed References
- TypeScript Patterns: See references/typescript-patterns.md for advanced types, generics, mapped types
- JavaScript Patterns: See references/javascript-patterns.md for JSDoc, ESM, performance
1---2name: typescript-javascript3description: TypeScript and JavaScript development standards for modern web and Node.js development. Covers strict TypeScript configuration, type safety patterns, ESM modules, async/await, testing with Jest/Vitest, and security best practices. Use when working with .ts, .tsx, .js, .mjs files, package.json, tsconfig.json, or when asking about TypeScript/JavaScript best practices.4---56# TypeScript & JavaScript Development78## Guiding Principles9101. **Type Safety**: Leverage strict mode, avoid `any`, use discriminated unions112. **Explicit Over Implicit**: Prefer explicit types for clarity and maintainability123. **Modern Defaults**: ESM, const/let, async/await, optional chaining134. **Security First**: Never use `eval`, sanitize HTML, validate inputs1415## Quick Reference1617| Aspect | TypeScript | JavaScript |18|--------|------------|------------|19| **Package Manager** | `pnpm` preferred | `pnpm` preferred |20| **Module System** | ES Modules | ES Modules + `// @ts-check` |21| **Linting** | `eslint --max-warnings=0` | `eslint --max-warnings=0` |22| **Formatting** | Prettier | Prettier |23| **Types** | Strict mode | JSDoc types |2425## Critical Patterns2627```typescript28// 1. Use strict equality29if (value === 0) { } // ✅ GOOD30if (value == 0) { } // ❌ BAD3132// 2. Handle Promise rejections33fetchData().catch(err => console.error(err)); // ✅ GOOD3435// 3. Optional chaining and nullish coalescing36const name = user?.profile?.name ?? 'Guest'; // ✅ GOOD3738// 4. Use Set/Map for lookups39const seen = new Set(); // ✅ GOOD (O(1))40const seen = []; // ❌ BAD (O(n))4142// 5. Never use eval or new Function43eval(userInput); // ❌ NEVER DO THIS4445// 6. Sanitize HTML46element.textContent = userInput; // ✅ GOOD47element.innerHTML = userInput; // ❌ BAD (XSS)48```4950## TypeScript Configuration5152```json53{54 "compilerOptions": {55 "target": "ES2022",56 "module": "ESNext",57 "moduleResolution": "bundler",58 "strict": true,59 "noImplicitAny": true,60 "strictNullChecks": true,61 "noUnusedLocals": true,62 "noUnusedParameters": true,63 "noUncheckedIndexedAccess": true,64 "esModuleInterop": true,65 "skipLibCheck": true66 }67}68```6970## Avoid `any` - Use Proper Types7172```typescript73// ❌ BAD - Loses all type safety74function processData(data: any): any {75 return data.value;76}7778// ✅ GOOD - Generic type79function processData<T>(data: T): T {80 return data;81}8283// ✅ GOOD - Unknown for truly unknown types84function processData(data: unknown): string {85 if (typeof data === 'object' && data !== null && 'value' in data) {86 return String((data as { value: unknown }).value);87 }88 throw new Error('Invalid data');89}90```9192## Discriminated Unions9394```typescript95type SuccessResponse = {96 status: 'success';97 data: { id: string; name: string };98};99100type ErrorResponse = {101 status: 'error';102 error: { code: number; message: string };103};104105type ApiResponse = SuccessResponse | ErrorResponse;106107function handleResponse(response: ApiResponse): void {108 if (response.status === 'success') {109 console.log(response.data.id); // Type-safe110 } else {111 console.log(response.error.message); // Type-safe112 }113}114```115116## Utility Types117118```typescript119interface User {120 id: string;121 name: string;122 email: string;123 password: string;124}125126type UserUpdate = Partial<User>; // All optional127type UserCredentials = Pick<User, 'email' | 'password'>;128type UserPublic = Omit<User, 'password'>; // Exclude password129type RequiredUser = Required<User>; // All required130type ReadonlyUser = Readonly<User>; // Immutable131```132133## Async Patterns134135```typescript136// Parallel execution137const [users, products] = await Promise.all([138 fetchUsers(),139 fetchProducts()140]);141142// Handle partial failures143const results = await Promise.allSettled([144 fetchUsers(),145 fetchProducts()146]);147148results.forEach(result => {149 if (result.status === 'fulfilled') {150 console.log(result.value);151 } else {152 console.error(result.reason);153 }154});155```156157## Security Rules (Mandatory)158159- Never use `eval`, `new Function`, or unsanitized `innerHTML`160- Use `textContent` for DOM insertion161- Validate and sanitize all external inputs162- Do not log secrets/tokens/PII163- Use parameterized queries; no string-built queries164- Enforce HTTPS; secure cookies (HttpOnly, SameSite)165166## Naming Conventions167168| Type | Convention | Example |169|------|------------|---------|170| Functions/Variables | camelCase | `fetchUserData` |171| Classes/Interfaces | PascalCase | `UserService` |172| Constants | UPPER_SNAKE_CASE | `MAX_RETRIES` |173| Types | PascalCase | `ApiResponse` |174175## Detailed References176177- **TypeScript Patterns**: See [references/typescript-patterns.md](references/typescript-patterns.md) for advanced types, generics, mapped types178- **JavaScript Patterns**: See [references/javascript-patterns.md](references/javascript-patterns.md) for JSDoc, ESM, performance179