# No implicit any types

- **Pattern:** `ab-002137` (`code-quality-essentials.type-safety.no-implicit-any`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-20
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002137
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002137)

## Why it matters

Implicit `any` is TypeScript's escape hatch — every untyped function parameter defaults to `any`, which propagates through the call chain and silently disables type checking for all downstream code that touches it. ISO 25010:2011 §6.5.4 classifies this as a maintainability defect. When `noImplicitAny` is off, a renamed field in an API response or database schema causes zero compile-time errors and surfaces only as a runtime crash or silent data corruption in production.

## Severity rationale

Critical because implicit `any` on a single function parameter can propagate silently through an entire call chain, making TypeScript's type guarantees meaningless for that code path.

## Remediation

Re-enable `noImplicitAny` (or use `strict: true`) and add explicit type annotations. Use `unknown` when the type is genuinely unknown at compile time — never `any` as a shortcut — then narrow at the callsite.

```typescript
// Bad: implicit any causes noImplicitAny error:
function transform(value) { return value.toString(); }

// Good: explicit type:
function transform(value: string): string { return value.toString(); }

// Good: unknown + runtime narrowing:
function parsePayload(raw: unknown): MyType {
  if (!isMyType(raw)) throw new Error('Unexpected shape');
  return raw;
}
```

## Detection

- **ID:** `no-implicit-any`
- **Severity:** `critical`
- **What to look for:** In `tsconfig.json`, confirm `noImplicitAny` is `true`. Note: if `strict: true` is set, `noImplicitAny` is implicitly enabled unless it is explicitly overridden with `false`. Check for `"noImplicitAny": false` anywhere in the tsconfig. Also scan source files for function parameters with no type annotations — these would be the type errors this flag surfaces. Look for patterns like `function process(data)` with no `: DataType` annotation, which implicitly makes `data: any`.
- **Detector snippet (shell-capable tools only):** If `jq` is available, read the explicit `compilerOptions.noImplicitAny` value. Output `"true"` or `"null"` means pass IF `strict: true` is set elsewhere. Output `"false"` fails regardless. Exit >=2 (file not found) — fall back to prose reasoning.

  ```detect-jq
  jq -r '.compilerOptions.noImplicitAny // "null"' tsconfig.json
  ```

- **Pass criteria:** Enumerate all relevant code locations. `noImplicitAny` is `true` (directly or via `strict: true`) and is not explicitly overridden to `false` with at least 1 verified location.
- **Fail criteria:** `noImplicitAny` is explicitly set to `false`, or `strict` is absent/false and `noImplicitAny` is not individually set. A partial implementation does not count as pass.
- **Skip (N/A) when:** Project has no TypeScript files.
- **Detail on fail:** `"noImplicitAny is disabled or not set; function parameters without type annotations default to 'any'"`
- **Remediation:** If you disabled `noImplicitAny` to silence errors during migration, re-enable it and add explicit type annotations. Use `unknown` when the type genuinely isn't known at compile time — never `any` as a shortcut:

  ```typescript
  // Bad: implicit any (causes noImplicitAny error):
  function transform(value) { return value.toString(); }

  // Good: explicit type:
  function transform(value: string): string { return value.toString(); }

  // Good: when type is genuinely unknown:
  function parsePayload(raw: unknown): MyType { ... }
  ```

## External references

- iso-25010 maintainability.modifiability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-002137
