Getting Started With TypeScript
Static vs. Dynamic Typing#
TypeScript has continued to rise in popularity since its initial release. To quote some recent numbers:
48% of npm users are using TypeScript
TypeScript joined the TIOBE index of 100 most popular programming languages in June 2018
TypeScript was voted the 4th most loved programming language in the 2018 Stack Overflow developer survey
We begin this chapter by exploring two fundamental questions:
What is TypeScript?
Why Should I Use TypeScript?
We will also build a small library that will expose us to practical examples of using TypeScript to solve real-world problems. By the end of the chapter, we'll have a solid understanding of what TypeScript is, why we should use it, and how it is used in practice.
What is TypeScript?#
The diagram below shows the relationship between TypeScript, ES5, ES2015+, and ESNext:
TypeScript supports ES5 and ES2015+ specs, but it does not support all ESNext features, which are features that are still making their way through the ECMAScript approval process. Two examples of this (at the time of writing) are the optional chaining operator and private class fields--two features which are available in most modern browsers.
letdeclarations Arrow functions Promises Modules Generators Iterators Object destructuring* Spread operator
Every feature listed above is available in TypeScript, and we'll see them used throughout the book. See Appendix A: ES2015 for an in-depth look at the features introduced in ES2015.
Not only does TypeScript support most ECMAScript features, it also introduces a syntax for annotating types.
Let's look at an example.
logGreeting function accepts a string
message and logs a greeting message constructed using the input string:
logGreeting, where an object is passed to the function as opposed to a string.
Running the code in any environment will produce an output similar to:
Object in our log isn't what we want! Instead, we'd like to only allow a string to be passed as the
message argument. If an object is passed to the function, we'd like to reject that value and require that a string is passed instead.
One potential solution is to add an if-statement that checks the type of the argument passed and throw an error if that type is not a string. Although this seemingly solves the problem, we won't see the error until we run the code, and this solution will be hard to scale for more complicated types, such as an object containing a specific set of values.
Catching Errors with Types#
With TypeScript, we can catch these errors without having to run the code, and if you are using an IDE with TypeScript support, you'll receive this feedback in real-time as you type.
We add a type annotation to
logGreeting to specify that the function only accepts strings:
By specifying that
message should be a string, we'll get the following error when compiling the code:
To fix the error, we need to pass a string to
logGreeting. The correct usage is to pass
person.name to the function:
This will compile without errors, and the new output of the function will be the expected greeting message:
Why Should I Use TypeScript?#
TypeScript helps us achieve the following:
Easier refactoring: we are able to easily change the modules and functions in our application with confidence that errors arising from those changes will be exposed at compile-time.
Intelligent code completion: our code editors are able to provide auto-complete functionality for the objects that are used in the application.
Early bug detection: typos, missing parameters, and mismatched types are examples of bugs that will be caught at compile-time.
Documentation: type annotations are great sources of documentation as they describe the inputs/outputs of functions and the structure of data in your application.
These benefits are helpful for projects of all size, but TypeScript also comes at a cost. You'll have to keep the following in mind when choosing TypeScript:
Learning curve: your team will have to invest time in learning TypeScript. It's important that every developer on the team is able to maintain and update types accurately.
Extra build step: you will have to configure TypeScript with your current build system, and depending on the size of the project, this build step could add several seconds to the total build time.
Third-party libraries: you will have to ensure that the third party libraries you are using have types that are up-to-date, which is usually not a problem for popular libraries, but smaller, more obscure libraries might have types that are nonexistent out of date. In later chapters we cover how to get around libraries that are not typed.
Over time the benefits will outweigh the cons as the penalty for choosing TypeScript is mostly fixed at the adoption point, and third-party support will improve as TypeScript's popularity continues to rise.