| name | typescript-type-safety |
| description | Enforce TypeScript type safety guidelines. Ensures proper typing, prevents type-related runtime errors. Focuses on mock data creation, enum handling, and complex type initialization. |
_typescript-type-safety
Overview
Ensures type-safe code in TypeScript projects. Prevents runtime errors through strict type checking, proper enum usage, and correct mock data creation.
When to use: Creating test mocks, handling enums, initializing complex types
Key principle: Never use as any or empty objects {} - always provide complete type initialization
Common Type Errors & Solutions
Error 1: Missing Required Properties
const user: UserProfile = {} as UserProfile
const user: UserProfile = {
id: '123',
name: 'John',
email: 'john@example.com'
}
Fix: Read interface definition, identify all required fields (no ?), provide values for each.
Error 2: Invalid Enum Values
status: 'pending'
import { Status } from './types'
status: Status.PENDING
Fix:
- Find enum definition
- List all valid values
- Use actual enum value, not string
Error 3: Incomplete Nested Objects
const config: AppConfig = {
databases: {}
}
const config: AppConfig = {
databases: {
primary: { host: 'localhost', port: 5432 },
cache: { host: 'localhost', port: 6379 }
}
}
Mock Factory Pattern
Create reusable factory functions for complex types:
function createMockUser(
overrides: Partial<User> = {}
): User {
return {
id: `user-${Math.random()}`,
name: 'Test User',
email: 'test@example.com',
status: Status.ACTIVE,
...overrides
}
}
const user = createMockUser({ name: 'Custom Name' })
Benefits:
- DRY (Don't Repeat Yourself)
- Single source of truth
- Type-safe
- Easy to maintain
Nested Type Factories
function createMockConfig(
overrides: Partial<Config> = {}
): Config {
return {
database: createMockDatabaseConfig(overrides.database),
cache: createMockCacheConfig(overrides.cache),
...overrides
}
}
function createMockDatabaseConfig(
overrides: Partial<DatabaseConfig> = {}
): DatabaseConfig {
return {
host: 'localhost',
port: 5432,
name: 'testdb',
...overrides
}
}
Enum Patterns
Initialize All Enum Keys
export interface Distribution {
[Category.TECH]: number
[Category.SCIENCE]: number
[Category.ARTS]: number
}
const dist: Distribution = {
[Category.TECH]: 0.5,
[Category.SCIENCE]: 0.3,
[Category.ARTS]: 0.2
}
const dist: Distribution = {
[Category.TECH]: 0.5
}
Enum Value Validation
export enum Status {
PENDING = 'pending',
ACTIVE = 'active',
INACTIVE = 'inactive'
}
const status = Status.PENDING
const status = 'pending' as Status
const status = 'archived'
Verification Process
1. Read Type Definition
2. Create Checklist
- [ ] Field1: type (required)
- [ ] Field2: enum type (valid values listed)
- [ ] Field3: object type (nested fields initialized)
3. Implement with Factory
function createMock(overrides = {}): Type {
return {
...overrides
}
}
4. Verify with Type Checker
npm run build
Quick Checklist
Before declaring a typed variable:
Common Pitfalls
| Issue | Check |
|---|
Using Partial<T> where T required | Provide defaults or validate at use site |
| Enum string vs enum value | Import enum, use enum value directly |
| Missing nested fields | Create factory functions for nested types |
Type assertion with as any | Remove assertion, let TypeScript guide you |
| Copy-paste wrong field name | Reference type definition directly |
Best Practices
- Create factory functions for types with 3+ required fields
- Use Partial for optional overrides in factory params
- Import enums directly - don't hardcode strings
- Document expectations with JSDoc for factories
- Run type checker after major changes
Related Skills
- _code-health-check: Validates type safety as part of pre-commit checks
- run_in_terminal: Execute
npm run build or tsc --noEmit for verification