In this post you will learn how to use the any
type in TypeScript, and most importantly - how to use it properly.
The any
type allows us to assign literally “any” particular value to that variable, simulating what we know as plain JavaScript - where types can dynamically be assigned from different types, such as a String value becoming a Number.
Table of contents
It’s a common “easy-fix” to declare types as any
, and through proper understanding of the type we can make the right decisions on when to use the any
type.
The any
type should really be used when we don’t actually know what type is actually coming back to us. This could be, for example, through a function argument that’s part of a third-party library and it doesn’t have any type definitions, as it could have been written in plain JavaScript and not TypeScript perhaps.
Free eBook
Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.
- Observables and Async Pipe
- Identity Checking and Performance
- Web Components <ng-template> syntax
- <ng-container> and Observable Composition
- Advanced Rendering Patterns
- Setters and Getters for Styles and Class Bindings
Typically, we know what the shape of the data structure or the arguments or a response looks like. However, in cases that we don’t know what the shape of something looks like, we want to know that the any
type is available for us to use.
The Any type
Let’s assume that we have a let
statement (a let
statement allows us to reassign a value whereas a const
does not) and we’ll say that the variable identifier is coupon
, and give it no type:
let coupon;
If we were to hover over this in our IDE we would see that it would say let coupon: any
, this is what we call an inferred type. We are letting TypeScript infer the type for us, instead of declaring it. This practice is called implicit typing. If we add a type ourselves, such as let coupon: any;
, that’s explicit typing.
As we’re using the let
keyword, we can essentially override whatever the value might be with any kind of type - acting more like plain JavaScript.
In plain JavaScript, we can assign any particular value to any particular variable, and we can also pass through any particular function argument and return any value from a function.
If we were to assign a number to the coupon
, it would indeed work. If we hover over coupon
in our IDE however, we would still have an any
type even though the value is a number!
// implicit typing, inferred as "any"
let coupon;
coupon = 26;
Even though it holds the value of a number, TypeScript does not change the
any
type to something else (such asnumber
). If we don’t supply a type, it will be of typeany
by default.
When to use Any in TypeScript
Use the any
type when there are no other options, and there are no type definitions available for that particular piece of code you’re working with.
For instance, if our coupon
was perhaps a variable from some place other than the code we’ve written, it could be expecting either a string
, number
, or even boolean
.
These are all entirely possible and valid values for a coupon
variable, depending on scenario:
let coupon: any;
coupon = 26;
coupon = 'DEAL26';
coupon = true;
There you have it. When to use the any
type, when you have no other option. And yes, we know, you can use it if you want to - but good habits create better code and proper type definitions will greatly benefit any codebase.
Using noImplicitAny in tsconfig.json
In your tsconfig.json
, you can be smarter and completely disable the potential of a leaving a type implicitly typed (such as let coupon;
):
{
"compilerOptions": {
"noImplicitAny": true
}
}
With noImplicitAny
set to true
, we will see a nice nudge from TypeScript to say “Hey, we agreed you weren’t going to do this!” if you decide not to type something, it’ll want you to add :any
.
There’s also another, shorter, way to enable noImplicitAny
under the relatively new strict
option:
{
"compilerOptions": {
"strict": true
}
}
The complete list of options that strict
will enable for us:
- noImplicitAny
- noImplicitThis
- strictNullChecks
- alwaysStrict
These options can all still be configured individually.
Remember, you can also use the command-line flags such as
--strict
or--noImplicitAny
. Feel free to reference the full list of Compiler Options.
Summary
The valuable takeaway here is that the any
type can save us in moments where needed, but it shouldn’t be used without valid reason. We can also aim towards a better codebase through reducing occurences of an implicitly typed any
.
Another valid use case for why you should use the any
type could be if you’re migrating a JavaScript project over to TypeScript, you may have some dynamic variables to which you assign different types to throughout a program - as you build up your own Types and Interfaces for the project.
Either way, I hope this post was useful and you learned a few new things - there’s lots more to learn with us over at Ultimate Courses, I’m the proud author of two TypeScript Courses, from beginner to advanced level (things you have seen in the documentation and thought “yikes”).
I’d love it if you would check them out!
Happy coding!