🎯

limit-any-type

🎯Skill

from marius-townhouse/effective-typescript-skills

VibeIndex|
What it does

Helps developers replace unsafe `any` types with precise TypeScript type definitions, improving type safety and code quality.

πŸ“¦

Part of

marius-townhouse/effective-typescript-skills(83 items)

limit-any-type

Installation

Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills --all
Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills -s prefer-unknown-over-any exhaustiveness-checking
Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills -a opencode claude-code
Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills -l
git cloneClone repository
git clone https://github.com/marius-townhouse/effective-typescript-skills.git
πŸ“– Extracted from docs: marius-townhouse/effective-typescript-skills
1Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Use when tempted to use any type. Use when getting type errors that seem hard to fix. Use when migrating JavaScript to TypeScript.

Overview

# Limit Use of the any Type

Overview

The any type effectively disables TypeScript's type checker for the code that uses it.

While any can be useful as an escape hatch, it eliminates the benefits of TypeScript: type safety, developer experience, refactoring confidence, and bug prevention.

When to Use This Skill

  • Reaching for any to silence a type error
  • Migrating JavaScript code to TypeScript
  • Working with third-party libraries without types
  • Feeling frustrated with complex type errors
  • Adding type annotations to existing code

The Iron Rule

```

NEVER use any without a specific, documented reason.

```

No exceptions:

  • Not for "it's just a quick fix"
  • Not for "the type is too complicated"
  • Not for "I'll fix it later"
  • Not for "it works at runtime"

Detection: The "any Smell"

If you're typing any, stop and ask: "Is there a better way?"

```typescript

// ❌ VIOLATION: Using any because it's "easy"

function processData(data: any) {

return data.items.map((item: any) => item.name);

}

// βœ… CORRECT: Define proper types

interface DataItem {

name: string;

}

interface Data {

items: DataItem[];

}

function processData(data: Data) {

return data.items.map(item => item.name);

}

```

The Five Dangers of any

1. No Type Safety

```typescript

let age: number;

age = '12' as any; // No error, but wrong!

age += 1; // "121" at runtime

```

2. Breaks Contracts

```typescript

function calculateAge(birthDate: Date): number { / ... / }

let birthDate: any = '1990-01-19'; // string, not Date!

calculateAge(birthDate); // No error, but will fail

```

3. No Language Services

```typescript

// With proper types: autocomplete, refactoring, documentation

person. // Shows: name, age, email...

// With any: nothing

(person as any). // No autocomplete

```

4. Masks Refactoring Bugs

```typescript

interface Props {

onSelectItem: (id: number) => void; // Changed from (item: any)

}

function handleSelectItem(item: any) {

selectedId = item.id; // Bug! Should be just item now

}

```

5. Hides Type Design

```typescript

// ❌ BAD: What is this state?

const appState: any = { / ... / };

// βœ… GOOD: Clear, documented design

interface AppState {

user: User | null;

preferences: UserPreferences;

isLoading: boolean;

}

```

Pressure Resistance Protocol

1. "It's Too Complicated"

Pressure: "The type is so complex, any is easier"

Response: Complex types often indicate complex data. Defining the type forces you to understand and document your data model.

Action: Break down the type. Use interfaces and type aliases. Ask: "What does this data actually look like?"

2. "I'll Fix It Later"

Pressure: "I'll come back and add proper types"

Response: You won't. Technical debt accumulates. any spreads through your codebase.

Action: Fix it now. If you truly can't, add a // TODO with a ticket number.

3. "The Library Doesn't Have Types"

Pressure: "This npm package has no @types"

Response: You have options: write minimal types, use unknown, or create a .d.ts file.

Action: Use unknown for values you don't control. Create focused interface for what you actually use.

Better Alternatives to any

| Instead of | Use |

|------------|-----|

| any for unknown values | unknown (forces you to narrow) |

| any[] | unknown[] or specific type |

| (x: any) => any | Proper function signature |

| Record | Record |

| any for JSON | Parse and validate with unknown |

Red Flags - STOP and Reconsider

  • Multiple any types in a single function
  • as any to silence errors
  • // @ts-ignore or @ts-expect-error to bypass checking
  • any in public API signatures
  • any in function return types

Common Rationalizations (All Invalid)

| Excuse | Reality |

|--------|---------|

| "It works at runtime" | Types exist to catch bugs BEFORE runtime. |

| "TypeScript is too strict" | TypeScript is protecting you. Learn what it's saying. |

| "I don't know the type" | Use unknown and narrow it. |

| "Third-party library" | Write minimal types for what you use. |

| "It's just internal code" | Internal code is still code. You'll debug it later. |

Quick Reference

| Symptom | Action |

|---------|--------|

| Type error you don't understand | Read the error carefully, use unknown |

| Complex nested type | Break into smaller interfaces |

| Dynamic data from API | Define response type, validate at boundary |

| Migrating from JS | Start with unknown, gradually add types |

The Bottom Line

Every any is a bug waiting to happen.

Use unknown for values you don't know. Use proper types for values you do. When you must use any, scope it narrowly, document why, and plan to eliminate it.

Reference

Based on "Effective TypeScript" by Dan Vanderkam, Item 5: Limit Use of the any Type.

More from this repository10

🎯
tsdoc-comments🎯Skill

Generates TypeScript documentation comments (TSDoc) to explain public APIs, complex types, and provide comprehensive code documentation with IDE tooltips.

🎯
async-over-callbacks🎯Skill

Transforms callback-based asynchronous code into clean, readable async/await patterns for better type flow and error handling.

🎯
ts-check-jsdoc-experiment🎯Skill

Enables gradual TypeScript type checking in JavaScript files using @ts-check and JSDoc annotations without full conversion.

🎯
create-objects-all-at-once🎯Skill

Efficiently initializes multiple TypeScript objects simultaneously using concise object literal syntax and spread operators.

🎯
functional-constructs-types🎯Skill

Explores advanced functional programming techniques and type system features in TypeScript for creating more robust and expressive code.

🎯
mirror-types🎯Skill

Mirrors external types locally to prevent tight coupling and isolate code from external type changes.

🎯
code-gen-independent🎯Skill

Generates JavaScript code despite TypeScript type errors and demonstrates that TypeScript types are erased at runtime, requiring alternative type checking strategies.

🎯
module-by-module-migration🎯Skill

Guides developers through systematic TypeScript module migration, breaking down complex refactoring into manageable, incremental steps.

🎯
ts-js-relationship🎯Skill

Explains TypeScript's relationship to JavaScript, highlighting how it adds static typing and catches errors before runtime while remaining fully compatible with JavaScript code.

🎯
type-display-attention🎯Skill

Displays and simplifies complex TypeScript types to improve IDE readability and developer experience.