TypeScript Best Practices Skill
When to use
- When writing any
.tsfiles. - When fixing type errors or refactoring legacy code.
- When the user asks to "fix types" or "improve type safety".
Guidelines
1. No any
- Avoid: Explicitly using the
anytype (data: any). - Why: It defeats the purpose of TypeScript.
- Fix: Use
unknownif the type is truly not known yet, or define a proper Interface/Type. Use type guards (if (typeof data === 'string')) to safely narrowunknown.
2. Type vs Interface
- Preference: Use
interfacefor object definitions (extensible) andtypefor unions, intersections, or primitives.interface User {id: string; name: string;} type UserId = string; type UserStatus = 'active' | 'inactive';
3. Utility Types
- Leverage standard utility types to avoid duplication:
- Partial<T>: Make all properties optional. - Pick<T, K>: Select specific keys. - Omit<T, K>: Exclude specific keys. - ReturnType<T>: Get return type of function.
4. Strict Mode Compliance
- Ensure code handles
nullandundefinedexplicitly. - Use optional chaining (
?.) and nullish coalescing (??) instead of loose checks.
5. Async/Await
- Always define return types for async functions (
Promise<T>). - Avoid
voidfor async functions unless it's a fire-and-forget event handler; preferPromise<void>.
6. Enums vs Unions
- Preference: Prefer String Literal Unions over numeric Enums.
- Why: Unions are simpler, lighter, and easier to debug.
// Good type Direction = 'UP' | 'DOWN'; // Avoid enum Direction {UP, DOWN}