typescript-guardian

This skill enforces TypeScript strict mode and type safety:

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "typescript-guardian" with this command: npx skills add d-oit/do-novelist-ai/d-oit-do-novelist-ai-typescript-guardian

TypeScript Guardian

Quick Start

This skill enforces TypeScript strict mode and type safety:

  • Strict mode compliance: Verify all strict flags enabled

  • Any type elimination: Replace any with specific types, unknown , or generics

  • Return type annotations: Add explicit return types to all functions

  • Type narrowing: Implement type guards and predicates

When to Use

  • TypeScript compiler errors need resolution

  • any types detected in production code

  • Missing return type annotations

  • Strict mode violations (unchecked index access, null/undefined)

Strict Mode Configuration

Current tsconfig.json requirements (already enforced):

{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true, "strictNullChecks": true, "noImplicitAny": true, "strictFunctionTypes": true } }

Verification commands:

Check for TypeScript errors

npx tsc --noEmit

Run type-aware linting

npm run lint:ci

Common Violations & Fixes

  1. Implicit Any

// ❌ Implicit any function process(data) { return data.value; }

// ✅ Explicit types function process(data: { value: string }): string { return data.value; }

  1. Unchecked Index Access

// ❌ No check for undefined const users = ['Alice', 'Bob']; const firstUser = users[0]; // string | undefined console.log(firstUser.toUpperCase()); // Runtime error if empty

// ✅ Check for undefined const firstUser = users[0]; if (firstUser !== undefined) { console.log(firstUser.toUpperCase()); }

// ✅ Or use optional chaining console.log(users[0]?.toUpperCase());

  1. Null/Undefined Not Checked

// ❌ Assuming value exists interface User { profile?: { name: string }; }

function greet(user: User): string { return Hello, ${user.profile.name}; // Error: profile might be undefined }

// ✅ Check for existence function greet(user: User): string { if (user.profile === undefined) { return 'Hello, stranger'; } return Hello, ${user.profile.name}; }

// ✅ Or use optional chaining function greet(user: User): string { return Hello, ${user.profile?.name ?? 'stranger'}; }

Any Type Elimination

Detection Strategy

Find any types in source code

grep -r ": any" src/ --include=".ts" --include=".tsx" --exclude="*.test.ts"

Find any[] array types

grep -r ": any\[\]" src/

Find type assertions with any

grep -r "as any" src/

ESLint enforces these rules (already configured):

  • @typescript-eslint/no-explicit-any : error

  • @typescript-eslint/no-unsafe-assignment : error

  • @typescript-eslint/no-unsafe-call : error

Replacement Patterns

Replace Any with Unknown:

// ❌ any (no type safety) function processData(data: any): void { console.log(data.value); }

// ✅ unknown (requires type narrowing) function processData(data: unknown): void { if (typeof data === 'object' && data !== null && 'value' in data) { console.log((data as { value: string }).value); } }

// ✅ Best: specific type interface Data { value: string; } function processData(data: Data): void { console.log(data.value); }

Replace Any with Generic:

// ❌ any loses type information function identity(value: any): any { return value; }

// ✅ Generic preserves type function identity<T>(value: T): T { return value; }

Replace Any with Union Type:

// ❌ any accepts anything function format(value: any): string { return String(value); }

// ✅ Union type is specific function format(value: string | number | boolean): string { return String(value); }

Replace Any with Type Predicate:

// ❌ any in type guard function isString(value: any): boolean { return typeof value === 'string'; }

// ✅ Type predicate with unknown function isString(value: unknown): value is string { return typeof value === 'string'; }

Return Type Annotations

ALWAYS add explicit return types (enforced by ESLint):

// ❌ Missing return type function getUser(id: string) { return db.query('SELECT * FROM users WHERE id = ?', [id]); }

// ✅ Explicit return type function getUser(id: string): Promise<User | null> { return db.query('SELECT * FROM users WHERE id = ?', [id]); }

// ✅ Void for no return function logError(error: Error): void { console.error('Error:', error.message); }

// ✅ Never for functions that don't return function throwError(message: string): never { throw new Error(message); }

Type Narrowing Patterns

Type Guards

// User-defined type guard function isUser(value: unknown): value is User { return ( typeof value === 'object' && value !== null && 'id' in value && 'name' in value && typeof (value as User).id === 'string' && typeof (value as User).name === 'string' ); }

// Usage function processData(data: unknown): void { if (isUser(data)) { console.log(data.name); // data is User here } }

Discriminated Unions

// Result type with discriminated union type Result<T, E = Error> = | { success: true; data: T } | { success: false; error: E };

function handleResult<T>(result: Result<T>): T { if (result.success) { return result.data; // TypeScript knows this is success branch } else { throw result.error; // TypeScript knows this is error branch } }

Assertion Functions

// Assert function (throws if condition fails) function assertDefined<T>( value: T | null | undefined, message = 'Value is null or undefined', ): asserts value is T { if (value === null || value === undefined) { throw new Error(message); } }

// Usage function process(user: User | null): void { assertDefined(user, 'User not found'); console.log(user.name); // user is User here }

Generic Constraints

// ❌ Unconstrained generic function merge<T>(obj1: T, obj2: T): T { return { ...obj1, ...obj2 }; // Error: Spread requires object }

// ✅ Constrained to objects function merge<T extends object>(obj1: T, obj2: T): T { return { ...obj1, ...obj2 }; }

// ✅ More specific constraint function merge<T extends Record<string, unknown>>( obj1: T, obj2: Partial<T>, ): T { return { ...obj1, ...obj2 }; }

Workflow

Phase 1: Analysis

  • Run tsc --noEmit to find errors

  • Scan for any types: grep -r ": any" src/

  • Identify missing return types

  • Prioritize by severity (compiler errors first)

Phase 2: Remediation

  • Replace any with unknown or specific types

  • Add explicit return type annotations

  • Fix null/undefined handling with guards

  • Add type narrowing where needed

Phase 3: Validation

  • Run tsc --noEmit (must pass)

  • Run npm run lint:ci (must pass)

  • Verify zero any types remain

  • Check all functions have return types

Common Issues

Array index flagged as potentially undefined

  • Solution: Check for undefined or use optional chaining

Object property access on potentially null/undefined

  • Solution: Use optional chaining and nullish coalescing: user?.profile?.name ?? 'Unknown'

Function parameters inferred as any

  • Solution: Add explicit type annotations: function process(data: { value: string })

Type assertion needed for external library

  • Solution: Create type definition file in types/ directory

Best Practices

Prefer Unknown Over Any:

// ✅ unknown requires type narrowing function parse(json: string): unknown { return JSON.parse(json); }

Use Type Assertions Sparingly:

// ⚠️ Type assertion (use only when certain) const user = data as User;

// ✅ Type guard with runtime check if (isUser(data)) { const user = data; // Type narrowed safely }

Document Complex Types:

/**

  • Result type for async operations
  • @typeParam T - Success value type
  • @typeParam E - Error type (defaults to Error) */ type Result<T, E = Error> = | { success: true; data: T } | { success: false; error: E };

Success Criteria

  • Zero TypeScript compiler errors

  • Zero ESLint type errors

  • No any types in production code

  • All functions have explicit return types

  • Strict mode compliance: 100%

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-quality-management

No summary provided by upstream source.

Repository SourceNeeds Review
General

iterative-refinement

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

agent-coordination

No summary provided by upstream source.

Repository SourceNeeds Review
Research

web-search-researcher

No summary provided by upstream source.

Repository SourceNeeds Review