typescript-strict
SKILL.md
TypeScript Strict Mode Enforcer
Ensure strict TypeScript practices and type safety across the Tetris codebase.
Core Principles
- No
anyTypes: Useunknownand type guards instead - No Type Assertions: Use type guards and narrowing
- No Non-null Assertions (
!): Use optional chaining and type guards - Result<T, E> Pattern: For game logic error handling
- Exhaustive Type Checking: Handle all union type cases
Type Safety Patterns
1. Replace any with unknown
// ❌ Prohibited
function process(data: any) {
return data.value
}
// ✅ Required
function process(data: unknown) {
if (isValidData(data)) {
return data.value // Type-safe after guard
}
return null
}
function isValidData(data: unknown): data is ValidData {
return (
typeof data === 'object' &&
data !== null &&
'value' in data
)
}
2. Avoid Type Assertions
// ❌ Prohibited
const element = document.getElementById('game') as HTMLCanvasElement
// ✅ Required
const element = document.getElementById('game')
if (element instanceof HTMLCanvasElement) {
// Type-safe usage
}
3. Use Optional Chaining
// ❌ Prohibited
const score = gameState!.score!.value
// ✅ Required
const score = gameState?.score?.value ?? 0
4. Result<T, E> Pattern for Game Logic
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
// ✅ Recommended for game logic
export const rotatePiece = (
piece: Piece,
board: Board
): Result<Piece, RotationError> => {
const rotated = calculateRotation(piece)
if (hasCollision(rotated, board)) {
return { ok: false, error: 'COLLISION' }
}
return { ok: true, value: rotated }
}
// Usage
const result = rotatePiece(currentPiece, board)
if (result.ok) {
setPiece(result.value)
} else {
handleError(result.error)
}
5. Exhaustive Type Checking
type Direction = 'UP' | 'DOWN' | 'LEFT' | 'RIGHT'
function move(direction: Direction): void {
switch (direction) {
case 'UP':
return moveUp()
case 'DOWN':
return moveDown()
case 'LEFT':
return moveLeft()
case 'RIGHT':
return moveRight()
default:
// Exhaustiveness check
const _exhaustive: never = direction
throw new Error(`Unhandled direction: ${_exhaustive}`)
}
}
Type Guard Patterns
Basic Type Guards
// String type guard
function isString(value: unknown): value is string {
return typeof value === 'string'
}
// Object type guard
function isGameState(value: unknown): value is GameState {
return (
typeof value === 'object' &&
value !== null &&
'board' in value &&
'currentPiece' in value &&
'score' in value
)
}
// Array type guard
function isStringArray(value: unknown): value is string[] {
return Array.isArray(value) && value.every((item) => typeof item === 'string')
}
Advanced Type Guards
// Discriminated union type guard
type Shape =
| { type: 'circle'; radius: number }
| { type: 'square'; side: number }
| { type: 'rectangle'; width: number; height: number }
function isCircle(shape: Shape): shape is Extract<Shape, { type: 'circle' }> {
return shape.type === 'circle'
}
// Usage
if (isCircle(shape)) {
console.log(shape.radius) // Type-safe
}
Error Handling Patterns
1. Result Type for Errors
type ParseError = 'INVALID_FORMAT' | 'MISSING_FIELD' | 'TYPE_MISMATCH'
function parseConfig(data: unknown): Result<Config, ParseError> {
if (!isObject(data)) {
return { ok: false, error: 'INVALID_FORMAT' }
}
if (!('boardSize' in data)) {
return { ok: false, error: 'MISSING_FIELD' }
}
if (typeof data.boardSize !== 'number') {
return { ok: false, error: 'TYPE_MISMATCH' }
}
return { ok: true, value: data as Config }
}
2. Never Type for Unreachable Code
function assertNever(value: never): never {
throw new Error(`Unexpected value: ${value}`)
}
// Usage in exhaustive checks
type PieceType = 'I' | 'O' | 'T' | 'S' | 'Z' | 'J' | 'L'
function getPieceColor(type: PieceType): string {
switch (type) {
case 'I': return 'cyan'
case 'O': return 'yellow'
case 'T': return 'purple'
case 'S': return 'green'
case 'Z': return 'red'
case 'J': return 'blue'
case 'L': return 'orange'
default:
return assertNever(type) // Compile error if case missed
}
}
Type Safety Checklist
- No
anytypes (useunknown+ type guards) - No type assertions (
as) - No non-null assertions (
!) - Result<T, E> for game logic errors
- Proper type guards for narrowing
- Exhaustive union type handling
- Optional chaining (
?.) for nullable values
Type Checking
# Run TypeScript type checker
bun run typecheck
# Watch mode during development
bun x tsc --noEmit --watch
When This Skill Activates
- "Fix type errors"
- "Improve type safety"
- "Handle this error properly"
- "Make this type-safe"
- "Add type guards"
- "Remove type assertions"
Weekly Installs
7
Repository
sakataka/tetris-game2First Seen
Jan 24, 2026
Security Audits
Installed on
claude-code4
trae4
gemini-cli3
antigravity3
windsurf3
codex3