Software systems to innovate and grow

Understanding Types in TypeScript

By Engineering Team January 22, 2017 10 mins read

I recently read this hilarious article about what it means to be a JavaScript developer in 2016.

The summary – working with JavaScript involves knowing a lot more than JavaScript. Remember the old days where we imported jQuery through a CDN and used that to manipulate a few things in the DOM or run some AJAX requests? That’s changed.

If you’re working with any modern JavaScript framework, you’ll most likely be writing code in ES6 or TypeScript or JSX, maybe using a templating engine like handlebars. You’ll also be using module loaders (like webpack) and automation tools (like grunt or gulp) along with package managers (mainly npm).

Now even though that may sound like a lot of work, it isn’t a bad thing! These tools and high-level frameworks can save you a lot of time and trouble.

Today we’ll talk about TypeScript and how you can work with it’s types.

 

Quick Overview of TypeScript

Here’s what the TypeScript’s website says –

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
Any browser. Any host. Any OS.

Now that’s definitely a mouthful. Let’s give that some context.

JavaScript was never meant to be used as the core language for building large scale web applications. In the past, building large scale applications meant working with a language like Java or C# – .net (just to name a few). Such languages usually leaned towards “strongly typed” (in a strongly typed language, each type of data is predefined, that means that once x is a string, it’ll continue to be a string in it’s current scope).

With such languages, you save a lot of time by avoiding runtime errors. But that’s not the case with JavaScript. Slam your keyboard if this has ever happened to you.

JavaScript Uncaught Type Error

or maybe this

JavaScript Cannot Read Property of Undefined

JavaScript was used to add a few quirks to the HTML page. It was just something you needed to use when you needed additional client side functionality. Which is why it made sense for it to be a “loosely typed” language.

But times have changed now. Today, so many developers are using JavaScript full-stack for large applications. That means that there is some room for improvement.

That’s exactly what TypeScript aims to do. The benefits of a strongly typed language that compiles to JavaScript.

Try It!

If you want to try TypeScript right now, you can install the TypeScript Compiler (tsc) by following the quick start intructions.

Or you could just punch in the code samples without having to install any packages with the TypeScript playground.

What are Types

Types are what makes TypeScript great. They prevent many runtime errors and allow IDEs to do their magic and show you where the errors lie.

If you’ve worked with other object oriented programming languages (like Java), everything we talk about below will hit right home. If all you’ve ever known is JavaScript, read on!

Take a look at this code.

JavaScript is probably one of the very few places you can do something like this. If we were working with an object oriented language (the example below is in Java), this is what the same code would look like.

And this is what the console output would be.

Java Compile Error

You may say… “That just makes things harder.” And you’d be right.

For a simple program like this, it doesn’t matter, but when things more complex, you want compile errors to save you from annoying runtime errors. Let’s take a look at one more example.

We wouldn’t see a problem until our program reached this bit of the code during runtime…

We’d know about the error as soon as the program would compile…

Java Incompatible Type Error

Imagine what will happen when this application gets larger!

Basic TypeScript Types

Even though we’ve been giving examples using Java, a more “strongly typed” language, that doesn’t mean TypeScript and Java are the same.

TypeScript is a superset of JavaScript. Which means that it allows us to work with the awesomeness of JavaScript. If you’re used to working with other object oriented languages, don’t be surprised if you see a data type that you’ve never seen before.

let

Before you can make sense of the examples below you need to know a bit more about the let keyword.

let‘s run through this really quickly!

Here’s how you declare a variable in JavaScript.

Here’s the problem…

You’d expect the output of this to be…

But the real output is…

That’s because JavaScript has very different scoping rules compared to other languages.

let is a block scope variable declaration present in TypeScript (and ES6). When it compiles down to JavaScript, all it does is rename the variables to make it seem as though we are using block scope variables. Even if we aren’t.

Here’s a crash course in using let with the same example…

That gives us the expected output…

It also rids us of the other scope-related quirks of JavaScript. You can read more about let here, but for now, this is all you need to know.

1.Boolean

This doesn’t need any explaining, does it? True or false?

2. Number

All numbers in TypeScript are floating point values. This means that whole numbers, as well as decimals, come under the type number.

TypeScript also allows us to declare hexadecimal, binary and octal literals.

3. String

There are three ways to use strings in TS.

  1. Double Quote Strings – let double: string = "double quotes";
  2. Single Quote Strings – let single: string = 'single quote';
  3. Template Strings – these are special.

Let’s look at an example of declaring template strings –

There are three things you need to notice in the templateString above –

  1. It is surrounded with backticks (`).
  2. We can use expressions within such a string using the ${expressionName} syntax.
  3. We can use single or double quotations within these strings.

To use backticks in template strings, just escape them with \.

4. Array

There are two ways to type protect an array…

But what if you wanted more than one type in your array – maybe a string and a number?

5. Tuple

These data types allow you to define an array where we know the type of a fixed number of elements. Here’s an example…

Any additional elements in the array are OK, but they must be a union type – i.e. either of the types we have specified in the tuple.

In our example, our tuple has two types – string and number. So any of the elements after the first three must either be a string or a number.

We’ll dive deeper into union types when we cover the advanced types in TypeScript in another article.

6. Enum

Enums are a friendly way of declaring numeric values. Have a look at this example where we only want to allow relatively sober people into our club to avoid any nonsense.

You can see how this is better than using constant or numbers directly. This makes the code much more readable and very safe.

By default, TypeScript assigns these enums values starting at 0. If for some reason we wanted to change that, we could…

We can also get the name of the value in the enum from the numeric value.

7. Any

There are cases where we may not know the types we are working with. That’s when we can use the any type.

Any is even more flexible than a JavaScript Object. We can’t use any methods other than those that are a part of JavaScript’s Object interface (like toString) – even if we define them explicitly.

8. Void

You use void when there is no type. This is useful when you are adding types to functions that don’t have a return value.

You could use void to declare variable types as well, but that isn’t very useful because only null and undefined can be of the type void.

Types on Functions

We didn’t add types to the return values in any of the functions above to keep the examples simple. Here’s how you would use functions with a return type.

9. Null and Undefined

null and undefined are subtypes of all other types. That means let value: number = null; is allowed. You could also use them on their own like let nullVal: undefined = undefined;. As you can see, that isn’t very useful.

So why have these types at all?

They become useful when you use the --strictNullChecks flag. That doesn’t allow type (other than void) to be null.

The last example uses the union type. We’ll talk more about that in the advanced TypeScript types (in another post).

10. Never

never is used for values that never occur.

Wait… What?

Look at this function…

This is what the output looks like…

Almost every JavaScript function returns a type – even console.log. When we don’t explicitly return a type in a JavaScript function, we implicitly return void.

Now take a look at something completely different…

Our final log statement would never be executed! So the startLoop function never returns a type. It just goes on and on!

No type is assignable to never other than never itself.

You can have a look at some more examples of never here.

Further Learning

You’ve come a really long way today! You’ve got a great grasp on TypeScript’s basic types.

But that’s not all the types TypeScript has to offer. We’ll be covering the advanced types in another article. If you can’t wait to read about them, click here.

Finally, after you’ve meddled around with some code, gone through the official docs, you may want to backtrack and look at an Introduction to TypeScript from the guys at Microsoft.

Who said learning has to be linear!

Happy “typing” (pun intended) 😉