No Explicit any Type

ID

javascript.ts_no_explicit_any

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

JavaScript

Tags

types, typescript

Description

Reports TypeScript type annotations that declare a value as any, including unions in which any is one of the alternatives (e.g. string | any). The any type opts out of every static check; the moment a value flows out of an any, every downstream call site silently becomes unchecked too.

Implicit any (a binding without an annotation) is out of scope for this rule — that is handled by enabling the TypeScript compiler’s noImplicitAny flag.

Rationale

// Bad — every call to `process` becomes a hole in the type graph.
function process(x: any): any {
  return x;
}

const cache: any = {};
class Service {
  data: any[] = [];
}

any defeats not only the immediate annotation but also every type that flows through it. Errors that would be caught at the any boundary are pushed downstream, often surfacing as runtime crashes far from the original site.

Remediation

Replace any with the concrete type you intended:

// Good — concrete types restore static guarantees.
function process(x: string): string {
  return x;
}

const cache: Map<string, number> = new Map();
class Service {
  data: string[] = [];
}

When the value really is open-ended, prefer:

  • unknown — keeps the value typed but forces a narrowing check before use.

  • A constrained generic — function process<T>(x: T): T.

  • A union of the actual values — string | number | boolean.

  • A discriminated union — { kind: "ok"; value: string } | { kind: "err"; reason: string }.