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 }.