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.
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.
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.
// 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;
}
ID: code-quality-essentials.type-safety.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.
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:
// 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 { ... }