Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Strict Typing

ASecurity

Use when writing code in typed languages - enforces full typing with no any/unknown/untyped escapes, even if it requires extra time

11 stars
0 votes
0 copies
2 views
Added 2/7/2026
developmenttypescriptpythonrustgojavac#expressrefactoringapidocumentation

Works with

api

Security Analysis

A100/100

Scanned 2/12/2026

$npx -y skills add troykelly/claude-skills --skill strict-typing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Strict Typing?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Strict Typing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/troykelly-strict-typing/badge)](https://www.skillsdirectory.com/skills/troykelly-strict-typing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: strict-typing
description: Use when writing code in typed languages - enforces full typing with no any/unknown/untyped escapes, even if it requires extra time
allowed-tools: []
model: opus
---

# Strict Typing

## Overview

No `any` types. No `unknown` escapes. Everything fully typed.

**Core principle:** Types are documentation that the compiler verifies.

**This skill applies to:** TypeScript, Python (with type hints), Go, Rust, Java, C#, and any typed language.

## The Rule

```
NEVER use any, unknown, or equivalent type escapes.
ALWAYS provide explicit, accurate types.
TAKE EXTRA TIME if needed to type correctly.
```

## TypeScript Specifics

### Forbidden Patterns

```typescript
// NEVER
const data: any = fetchData();
const items: unknown[] = parseItems();
function process(input: any): any { }
const config = {} as any;
// @ts-ignore
// @ts-expect-error (unless truly necessary with documentation)
```

### Required Patterns

```typescript
// ALWAYS
interface UserData {
  id: string;
  name: string;
  email: string;
}

const data: UserData = fetchData();

function process<T extends Processable>(input: T): ProcessResult<T> {
  // ...
}
```

### Configuration

Ensure `tsconfig.json` has strict mode:

```json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "noUncheckedIndexedAccess": true
  }
}
```

### Handling Third-Party Types

When library types are missing:

```typescript
// Create type definitions
declare module 'untyped-library' {
  export interface Config {
    option1: string;
    option2: number;
  }

  export function init(config: Config): void;
}
```

Or contribute types to DefinitelyTyped.

### Handling Dynamic Data

For API responses or parsed JSON:

```typescript
// Define expected shape
interface ApiResponse {
  users: User[];
  pagination: Pagination;
}

// Use type guard for runtime validation
function isApiResponse(data: unknown): data is ApiResponse {
  return (
    typeof data === 'object' &&
    data !== null &&
    'users' in data &&
    Array.isArray((data as ApiResponse).users)
  );
}

// Use with validation
const response = await fetch('/api/users');
const data: unknown = await response.json();

if (!isApiResponse(data)) {
  throw new Error('Invalid API response');
}

// data is now typed as ApiResponse
```

### Using Zod for Runtime Validation

```typescript
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email(),
});

type User = z.infer<typeof UserSchema>;

// Parse and validate
const user = UserSchema.parse(unknownData);
// user is now typed as User
```

## Python Specifics

### Forbidden Patterns

```python
# NEVER
def process(data):  # Missing type hints
    pass

def fetch() -> Any:  # Using Any
    pass

from typing import Any
result: Any = compute()
```

### Required Patterns

```python
# ALWAYS
from typing import TypeVar, Generic, Protocol
from dataclasses import dataclass

@dataclass
class User:
    id: str
    name: str
    email: str

def process(data: User) -> ProcessResult:
    ...

T = TypeVar('T', bound='Processable')

def transform(items: list[T]) -> list[T]:
    ...
```

### Configuration

Use strict mypy settings:

```ini
# mypy.ini
[mypy]
strict = True
disallow_any_generics = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
warn_redundant_casts = True
warn_unused_ignores = True
```

## Go Specifics

Go is statically typed, but avoid:

```go
// AVOID
interface{} // empty interface
any         // Go 1.18+ alias for interface{}

// PREFER
type specific interfaces or concrete types
```

When `interface{}` is truly needed, document why and add type assertions.

## When Typing Is Hard

If typing seems impossible:

### Step 1: Question the Design

```
Is the type hard to express because the design is complex?
→ Consider simplifying the design
```

### Step 2: Use Generics

```typescript
// Instead of any
function process<T>(input: T): T {
  return input;
}
```

### Step 3: Use Union Types

```typescript
// Instead of any for multiple types
type Input = string | number | User;

function process(input: Input): void {
  if (typeof input === 'string') {
    // input is string
  } else if (typeof input === 'number') {
    // input is number
  } else {
    // input is User
  }
}
```

### Step 4: Create Type Guards

```typescript
function isUser(value: unknown): value is User {
  return (
    typeof value === 'object' &&
    value !== null &&
    'id' in value &&
    'name' in value
  );
}
```

### Step 5: Document and Justify (Last Resort)

If `any` is truly unavoidable (extremely rare):

```typescript
// JUSTIFIED: Third-party library `foo` has no types and
// creating accurate types requires reverse-engineering
// the entire library. See issue #123 for type contribution.
// TODO(#456): Remove when @types/foo is available
const result: any = thirdPartyCall();
```

This should be exceptionally rare.

## Time Investment

Proper typing takes time. That's acceptable.

| Situation | Acceptable Time |
|-----------|-----------------|
| Simple interface | 5 minutes |
| Complex generic | 30 minutes |
| Type guards | 15 minutes |
| Library types | 1 hour |

If typing is taking longer, the design may need reconsideration.

## Checklist

Before committing code:

- [ ] No `any` types
- [ ] No `unknown` without type guards
- [ ] No `@ts-ignore` or `# type: ignore`
- [ ] All functions have typed parameters
- [ ] All functions have typed return values
- [ ] All interfaces/types are exported if public
- [ ] Type configuration is strict

## Common Excuses Rejected

| Excuse | Response |
|--------|----------|
| "It's just temporary" | Temporary code becomes permanent. Type it now. |
| "I'll fix types later" | Later never comes. Type it now. |
| "any is faster" | Technical debt is slower. Type it now. |
| "The library has no types" | Create types or use Zod. |
| "It's too complex to type" | Simplify the design. |

## Integration

This skill is applied by:
- `issue-driven-development` - Step 7

This skill ensures:
- Self-documenting code
- Compile-time error catching
- Refactoring safety
- Better IDE support

Attribution

troykellytroykelly
View sourceSee grades on GitHubMore from troykelly →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Clean Code

Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments

304955 votes

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

285172 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

10341 votes
View all in development →