05 - TypeScript: Seven Other Basic Types
Episode transcript for the podcast “Listen, Learn, and Code”. See podcast overview for more episodes and additional information.
Transcript
Hello and welcome to “Listen, Learn, and Code”. In one of the previous episodes, we were already playing with the “string” data type. In this episode, we will take a look at seven other basic types that you might already know from other programming languages. So, get ready, and let’s get started!
At the prospect of going through basic data types, some of the more experienced listeners among you might feel like “Booooring!”. Anyway, it won’t take long, and you might even hear one or two things that are still new for you. So bear with me, and we will have a solid foundation for the next episodes, which are going to deal with the more funky, TypeScript-specific stuff.
Let’s start with the easiest type, which is boolean
. The boolean type can have one of two values, namely true
and false
. These two values are written in lowercase characters, and of course without quotes - because, as we have already heard, we use quotes for string values. For example, if we want to assign the boolean value true
to the variable x
, we write:
let x: boolean = true
Remember that explicitly declaring the type in such a simple case is useless and can even be regarded as bad style. So we could have also written
let x = true
and let TypeScript infer the type of x automatically. One reason why I’m doing this here is that the repetitions will help you memorize the syntax. And the other reason is that it makes it easier to explain some basic principles. For example, in the following code:
let x: boolean = "hello"
Here we try to assign the string “hello” to a boolean variable, which is not allowed in TypeScript. As we’ve said before, boolean can hold only the values true
and false
, but not the string “hello”. You can think of types as bags of things. So the boolean type is a bag that holds the two things true
and false
, and the string type is a huge bag that holds all possible string values, like “abc”, “foobar”, “Hello World”, and so on. If you try to assign something from the string bag into the boolean bag, the boolean bag will complain that only true
and false
are OK, and that strings are not OK. Speaking in more mathematical terms, you can think of types as sets of values, and assignments are only possible if the two sets are equal, or if the receiving set (on the left side of the assignment) is a superset of the one on the right side. This is not the case in the previous, wrong example: the “string” set has nothing in common with the boolean set, which means that this assignment is forbidden.
Now on to the next data type, which is “number”. Here is a simple example:
let x: number = 21
In this example, we have assigned the integer 21 to the variable x. TypeScript doesn’t distinguish between integers and floating point numbers, so you can also write the following:
let x: number = 2.1
So you write the same type annotation called “number” both for integers and floating point numbers.
Just like “string”, the “number” data type is huge, but it has limits. If you ever need integers that are bigger than allowed by the “number” type, you can use the “bigint” type. There are two ways to define such a big integer. The first way is
let x: bigint = 21n;
This means that you have to write a lowercase “n” directly after the number. The second way is this:
let x: bigint = BigInt(21)
Note that the type assertion “bigint” on the left side of the assignment is written in lowercase characters, just as “string” and “boolean”. On the right hand of the assignment, we have the “BigInt” function, which is written in camel case, meaning with an uppercase ‘B’ and an uppercase ‘I’ (Big-Int). And a hint for the Java people out there: We don’t write “new BigInt” on the right side, but only “BigInt”, without “new”.
Also note that bigint only works if you configure TypeScript with a target of at least ECMAScript 2020. We have already seen how to configure the target in the previous episode.
The next important data type are arrays, which you can imagine as lists of values with a certain data type. We can write the type annotation for an array by appending square brackets to the element type. So for example, if you want an array of strings, you write string[]
. If you want the array to hold numbers instead of strings, you write number[]
. To initialize an array with values, you enclose the values in square brackets. For example, you can create a number array that contains the numbers 1 and 2 like this:
let x: number[] = [1, 2]
Now on to the type for objects, which is called… object (again, all in lowercase characters). An object is basically some “thing” with properties, and each of these properties has a name and a value. For example, let’s consider a product that you can buy in a supermarket. A property of such a product object could be the price. So the name of the property is “price”, and the value is some number. The initialization of an object works with curly brackets. So if you want to create an object that has the price 10, you could write the following:
let x: object = {
price: 10
}
Now don’t get confused here: When you initialize object properties, there is a colon between the property name and the value, and not an equals sign. So we don’t write price = 10
to define the property value, but price: 10
, even if this looks like a type annotation because of the colon. If we want to explicitly specify the type of the “price” property, we have to do so in the type annotation of the whole object, which we will do in a minute. But first, let’s see why writing let x: object
like we did before is a bad idea: If we want to access the price of the object x, we type x.price
. But here, TypeScript complains that the property “price” does not exist on the type “object”. So by using the explicit type annotation “object”, we have told TypeScript that this is just some object about which we don’t know any details. We practically force TypeScript to ignore that this object obviously has a “price” property. If we remove the “object” type annotation, TypeScript automatically infers the correct type, and stops complaining when you access the price.
Now let’s see how we can explicitly tell TypeScript that the “price” property shall be a number:
let x: { price: number } = // rest as before
So instead of the “object” type annotation on the left side of the assignment, we use a more detailed object type that says: Here is a property named “price”, and it has the type “number”. Of course, it would be quite tedious to repeat this detailed object type in every place where we need it. What we can do instead is define the object type once, and reuse it in other places. For this definition, we can either use a so-called “type alias”, or an “interface”. But more on this another time.
Object properties are a nice bridge to the next data type, which is “symbol”. As I’ve mentioned before, object properties are basically key-value pairs. In the previous example, we had a property with “price” as the key, and the number 10 as value. The key in this case was a string, even though we didn’t have to write it in quotes. But we could have explicitly written the following instead, which looks like JSON syntax:
"price": 10
But writing property keys with quotes like this is quite unusual, because it’s easier just to skip them. So far, so good, but what does this have to do with the “symbol” data type? A symbol is the only data type other than “string” that can be used for the keys of object properties. And that is probably all you have to know about the symbol type, because it’s very unlikely that you will ever have to deal with it.
And now, let’s move on to the final type in this episode, which is… “RegExp”. “RegExp” stands for “Regular Expression”, and is written in camel case with capital R and capital E: “Reg - Exp”. Regular expression values are written with two slashes, for example:
let x: RegExp = /hello/
In a nutshell, regular expressions can be used to find certain patterns in strings. So with the previous regular expression (/hello/
), you could check if some string contains the word “hello”. But regular expressions are much more powerful than that: For instance, you can use them to check if a string has some expected format, like a phone number, or a zip code. They are not specific to TypeScript or JavaScript, but a general concept that appears in many other programming languages. So in contrast to symbols, it is very likely that you will have to deal with regular expressions if you do programming.
So to sum up what we did in this episode:
After the “string” data type from episode #3, we learned about 7 more basic types. These are:
- boolean (for true and false values)
- number (for both integers and floating point numbers)
- bigint (for very big integers)
- arrays (which contain values of a certain type)
- objects (which have their own specific properties, or key-value pairs)
- symbols (which are probably not so relevant for you)
- and regular expressions (for finding patterns inside strings)
And that’s all for now. I hope you enjoyed this episode, and hear you next time on “Listen, Learn, and Code”.