| name | typescript-dev |
| description | TypeScript development best practices, code quality tools, and documentation templates. Activated when working with .ts, .tsx files or TypeScript projects. |
| allowed-tools | ["Read","Glob","Grep","Bash"] |
TypeScript Development Expert
This skill supports TypeScript project development.
๐ฏ Core Rules
Package Management
- Required: Use
pnpm as package manager
- Do not use
npm or yarn
Type Safety
- tsconfig.json:
strict: true required
- Null Handling: Leverage optional chaining
?. and nullish coalescing ??
- Imports: Use ES modules, avoid
require()
- NO ANY: Do not use
any type in production code
Best Practices
- Type Inference: Let TypeScript infer when obvious
- Generics: Use for reusable components
- Union Types: Prefer union types over enums for string literals
- Utility Types: Leverage built-in types (Partial, Pick, Omit)
Documentation
- Required: Use TSDoc format for documentation comments
- Public APIs only: Document exported functions, classes, and interfaces
- Self-documenting code: Prefer clear naming over excessive comments
- Document when necessary: Add TSDoc only when the code intent isn't obvious from the signature
๐ ๏ธ Code Quality Tools
Development Workflow
pnpm run format
pnpm run lint
pnpm tsc --noEmit
pnpm test -- --coverage
๐ฏ Quality Checklist
Check these during code review:
๐ Common Patterns
Error Handling
class ValidationError extends Error {
constructor(message: string, public field: string) {
super(message);
this.name = 'ValidationError';
}
}
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
Async/Await
async function fetchUserData(id: string): Promise<Result<UserData>> {
try {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
return { success: true, data };
} catch (error) {
return { success: false, error: error as Error };
}
}
Type Guards
function isUserProfile(value: unknown): value is UserProfile {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
'username' in value
);
}
๐ก Performance Tips
-
Avoid unnecessary re-renders (React)
- Use
React.memo for expensive components
- Use
useMemo / useCallback appropriately
-
Lazy Loading
- Dynamic imports for code splitting
React.lazy() for components
-
Type-only imports
import type { UserProfile } from './types';
๐ Common Anti-patterns to Avoid
โ Don't:
function process(data: any) { }
function getValue(obj, key) { }
const user = data as User;
โ
Do:
function process(data: UserData) { }
function getValue<T>(obj: T, key: keyof T) { }
if (isUser(data)) {
}