Stop using ANY in TypeScript right now. 🟦🧙‍♂️
Tags: webdev, typescript, beginners, programming
Published: 2023-10-26 04:00:00

### Hello coders! 🧙‍♂️

How many times in your career have you used the `any` type in TypeScript? Well, most people use this special type everyday, however what if I told you *you should completely stop using it*?

That's right. As a TypeScript developer, you should stop using `any`. Let's dive deeper into this and I'm sure I'll convince you at the end and you'll become a *real* TypeScript lover. 💙

![When you don't know what type you should use in TypeScript. Any.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7vygmp4ju773xjzrftm.jpg)

### *any* type in TypeScript

The `any` type makes it into the category of "primitive types" in TypeScript. These are `number`, `string`, `boolean`, `BigInt` (from ES2020), `symbol` (not very common), `undefined`, `null`, `void`, `never`, `unknown` and lastly `any`.

However `any` is a special type, since it can be used when you don't want a particular value to cause typechecking errors.

TypeScript Documentation says:

> When a value is of type any, you can access any properties of it (which will in turn be of type any), call it like a function, assign it to (or from) a value of any type, or pretty much anything else that’s syntactically legal.

And that's the reason why, *unless you have some real issue, like libraries with no typing or old JavaScript code*, you **should never use `any`**.

### The unsafety of *any*

Since `any` type prevents any type-check, you can do literally whatever you want to do with it. E.g.:

```ts
let bar: any = { foo = 1 };
bar.foo; // Ok
bar.hello; // Ok ?
bar(); // Ok ??
bar.trim(); // ok???
new bar(); // ok...
bar[0][1][4]; // what the hell??
```

This **will not throw any compiler error** and, unless really specific cases, it's absolutely wrong, since it totally destroys TypeScript purpose, type checking.


![TypeScript as a knight with an armor. Arrow hits the knight perfectly on the only open way.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ojicvlqfv8vige7gbdd.jpg)

### The type-safe *any*: *unknown*

Fortunately, for 100% code type-safety, there's an alternative for `any`, the `unknown` type.

The `unknown` type works the same as `any`, but with compiler errors if you don't specify the exact type you expect. For clarity, here's an example:

```ts
let safeBar: unknown = "Hello world";
safeBar.hello; // Error thrown
safeBar(); // Error thrown
// etc...
```

This could be useful in case you literally don't know what type a variable is. Check this other example:

```ts
function parseApiResponse(response: string): unknown {
    try {
        return JSON.parse(response);
    } catch (error) {
        return null;
    }
}

const apiResponse = '{ "name": "John", "age": 30 }';
const parsedData = parseApiResponse(apiResponse);

if (typeof parsedData === 'object') {
    // Now, you can safely access properties without TypeScript errors
    const name = (parsedData as { name: string }).name;
    const age = (parsedData as { age: number }).age;

    console.log(`Name: ${name}, Age: ${age}`);
} else {
    console.log('Failed to parse API response');
}
```

In this example, the "parseApiResponse" function returns data of type "unknown" because the actual structure of the data is not known at compile time. You can use type assertions (e.g., `(parsedData as { name: string }).name)` to access properties safely when you've checked the type. This way, you maintain type safety even when dealing with data of an unknown structure.

### How to prevent *any* in your code

You can start preventing `any` in your code by modifying your `tsconfig.json` file. Set the `noImplicitAny` property to `true`, to check if no type annotations are present for a variable. Normally, in that case, TypeScript will fall back to a type of `any` for a variable when it cannot infer the type.

```ts
{
  "compilerOptions": {
    /* ... */
    "noImplicitAny": true,
    /* ... */
  }
}
```

Check this example:
With `noImplicitAny: false`:

```js
function fn(s) {
  // No error?
  console.log(s.subtr(3));
}
fn(42);
```

With `noImplicitAny: true`:
```ts
function fn(s) {
// Error: Parameter 's' implicitly has an 'any' type.
  console.log(s.subtr(3));
}
```

If you use EsLint as your main linter, you may also install `@typescript-eslint` plugin to get the `noExplicitAny` rule. Example:

```ts
function fn(s: any): any {
// Error: Unexpected any. Specify a different type. - eslint@typescript-eslint/no-explicit-any
  console.log(s);
  return s;
}
```

### Who am I? 

I am an Italian high-school student who is interested in web-dev 🧙‍♂️. If you'd like to support me, you can follow me here and on my [GitHub](https://github.com/alessandrofoglia07), I would really appreciate it 💜