Description
Proposal: noAny
Flag
π Search Terms
noAny, no, any, flag, uknown
β Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
β Suggestion
It would be nice to have a noAny
flag that disallowed the use of any
at all, including implicitly and explicitly. Instead, the much safer alternative unknown
would be used. Many developers feel that any
is far too permissive and should never be used.
With this flag, the following would be the case:
let value: any; // Compile error: any not allowed, consider using "unknown" instead
instead of the current:
let value: any; // No error
Functions that return any
as part of the standard library (or other libraries) would either require a cast:
let value = functionThatReturnsAny(); // Compile error: any not allowed, consider casting to unknown
let value2 = functionThatReturnsAny() as unknown; // Fine! value is of type unknown.
Or, a much bigger ask, the compiler could automatically convert these to unknown
.
π Motivating Example
Consider a project manager that wants to write extremely type-safe code to avoid uncaught runtime errors; This is exactly what TypeScript is designed for. However, he finds his junior developers littering their code with any and making it extremely unsafe. In this case, a noAny
flag could be used to prevent these mistakes.
Additionally, it'd be a nice check in general for any developers to have; It is often considered good practice to avoid any
as much as possible, and everything possible with any is possible in a more safe way using unknown
:
let value: any = 3;
console.log(value.trim()); // Runtime error, none at compile-time
let value2: unknown = 3;
if (typeof value === "string") console.log(value.trim()) // Type-safe!
The new version would disallow the first example because it is not type-safe, and require the second be used instead. instanceof
and in
checks can also be used to narrow unknown
. Code written under this flag may be more verbose or lengthy, but it will be safer and cause less runtime errors.
π» Use Cases
This could be used for any project/developer that prefers stricter type checking, which may of us, as TypeScript developers, tend to prefer.
The any
type feels like exactly what TypeScript's creation was trying to prevent, and yet there is currently no way to disable it entirely (there is an eslint rule for it, but it is not a part of the TypeScript compiler options itself and even then can't enforce function calls that return any
); Only implicit any
s can be disabled, and even then they can be missed by being returns from function calls someone else wrote:
file1.ts:
function someoneElsesFunction(): any {
...
}
file2.ts (with noImplicitAny
enabled):
let value = someoneElsesFunction(); // No error! an `any` has snuck into your code.
Overall, this seems like a practical feature that would be highly desirable for many developers that prefer type-checking to be as strict as possible.