31
Why you should not use the type any in TypeScript
TypeScript is a fantastic programming language. With its typing layer on top of JavaScript, TypeScript verifies that your program uses the right type as you write code, avoiding potential issues at runtime.
In JavaScript, you reassign any type to any variable, or even access attributes that do not exist. Not with TypeScript since TypeScript checks types, ensuring only a value of the correct type to a variable or that attributes from an object actually exist.
For example, let’s take the following code.
let foo: number = 42;
foo = "bli";
This code assigns a string to a variable that can only contain numbers and, therefore, will raise the following error at compile-time, as shown below.
Typescript error for not using the correct type.
You can even notice that your development environment will show an error to highlight this error.
The special type any
is used to tell TypeScript that a variable can be of any type. A variable with the type any
means can be a string , a number or anything else!
If our previous block of code is updated to use any, assigning a string to it is allowed, as shown below.
You can reassign any type to a variable annotated with any
Using any
removes all type checking provided by TypeScript, which is one major reason for using TypeScript over JavaScript. By using any
, you expose yourself to issues that are difficult to trace and debug, especially once the code is deployed in production.
In other words: using any
for a variable type in TypeScript is similar to write JavaScript.
Hopefully, there are some alternatives!
The first one (and the best one) is to use the right type for your variable. Too often, developers use any because they use a function taken from third-party libraries or external websites (e.g., Stackoverflow) and don’t know what type is returned!
To save time and avoid understanding what type is used, developers take a shortcut, use any for the variable type, which will later create issues when the code is updated (what if the type of object returned by the third-party library changes? what if you try to access an attribute deprecated in new revisions of the library?)
Instead, it is important to understand the type being returned and type your variable accordingly. Take the time to understand the code you copy/paste from somewhere else and take the time to understand the library you are integrating into your code. Understanding the type being used will save you time and avoid bugs, but it will ensure you understand this code and ensure this solves the problem you are working on.
The second option is to use unknown
when you actually do not know the type and want to ensure type safety. When using unknown
, you can associate all types to a variable, but you cannot assign a variable with the unknown
type to another variable with a type.
According to the Pull Request that introduced unknown in the TypeScript language:
This PR adds a new top type
unknown
which is the type-safe counterpart of any. Anything is assignable tounknown
, butunknown
isn't assignable to anything but itself andany
without a type assertion or a control flow based narrowing. Likewise, no operations are permitted on anunknown
without first asserting or narrowing to a more specific type.
Let’s give some concrete examples. The following code works when using any
, this is a totally legit code block which is problematic because it does not make use of all type checking features of TypeScript and exposes you to potential typing issues in the future.
let foo: any = 42;
let bar: string = foo;
But the same code using unknown
(see below) does not work since a variable with the unknown
type cannot be assigned to a variable with a type.
let foo: unknown = 42;
let bar: string = foo;
You can use it directly in your VS Code or IntelliJ environment using an integration plugin that checks your TypeScript code in seconds:
Finally, the very same rules can be checked at each Pull Request on GitHub. You can install the Code Inspector GitHub app to ensure all your TypeScript code uses good development practices at each code change.
31