Welcome to part 4 in my ongoing guides to improving with TypeScript.
Be sure to check out my other guides on Union Types, Utility types, and Type Checking in TypeScript!
In this post, we'll take a look at how you can use arrays to store collections of TypeScript data types.
More specifically, we'll dive into:
Be sure to read through each part, as they all build onto each other, and you'll find array of arrays easier to understand.
Sidenote: If you're struggling to figure out arrays and how to use them, want to learn more, or simply just want a deeper dive into TypeScript, then check out my complete course on Typescript here.
It takes you from a complete beginner to building real-world applications and being able to get hired, so there's something for every level of TypeScript user.
Check it out above, or watch the first videos here for free.
With that out of the way, let's get into arrays in TypeScript and how they work...
An array is a container that permits storing multiple piece of data sequentially, sort of like items on a shopping list, or a series of emails.
This means that they are the go-to choice for storing data in a flat, sequential format.
Arrays can be assigned to a single variable which simplifies access and makes it easier to use the array throughout the program.
We call these items in an array, array elements, and they are all assigned an index. The index starts at 0 for the first element, and increases by 1 for each new element added.
For example
If we have an array containing the elements ['a', 'b', 'c']
then it will have indexes 0, 1, 2
.
When using arrays, it is important to remember that multiple elements are being processed. This means that most of the time we'll need to either:
Again, this will all get more clear as we go on, so don't worry if you're struggling to follow for now.
To create an array, square braces ([]
) are used, along with the type of the elements that will be contained within the array.
For example
If we wanted to store a list of names as strings
, we can do so like this:
// A variable of type string array, pointing
// to an empty array.
const names: string[] = [];
However, it's important to remember to always include the data type when declaring arrays in TypeScript, as failure to do so will result in unwanted behavior or a compiler error, like so:
const names = [];
// ERROR: `string` cannot be assigned to `never`
names.push("Amanda");
But, if we change the type annotation to include string[]
, this then tells TypeScript that we want to store string
data in the array.
Now the code will compile and run just fine:
const names: string[] = [];
names.push("Amanda");
Boom!
To insert data into an array, we use the push method shown in the previous code samples.
For example
push
will place data onto the end of the array.
This means that if we have a list of numbers [1, 2, 3]
and we use array.push(4)
then it will result in the array [1, 2, 3, 4]
, with the 4 added on the end of the array:
const nums: number = [1, 2, 3];
nums.push(4);
// [1, 2, 3, 4]
Simple!
However, sometimes we'll need to insert some data in a location other than the end of the array.
For these situations, we can use the splice method to pick the exact location where the data will get inserted instead.
For example
If we have an array of letters ['a', 'b', 'd']
and we want to insert the letter 'c'
into the correct position alphabetically, we can do this:
// index 0 , 1 , 2
const letters: string[] = ['a', 'b', 'd'];
letters.splice(2, 0, 'c');
// [ 'a', 'b', 'c', 'd' ]
A simple concept but let's look at how it works.
splice
takes three arguments:
If we look at the previous example
2
which corresponds to the letter d
in the array0
, and insert the letter c
at index 2
2
is already occupied with the element d
, the d
gets shifted over and c
gets inserted with index 2
Start here, add this, move this across. Easy!
To access an array element, we need to first know its index.
For example
In order to access an element at index 1
, we can do this:
const letters: string[] = ['a', 'b', 'c', 'd'];
const elemOne = letters[1];
// 'b'
We can use the same syntax to edit elements within an array. We just move the []
to the other side of the =
, like so:
const letters: string[] = ['a', 'c', 'b'];
letters[1] = 'b';
letters[2] = 'c';
// `['a', 'b', 'c']`
Accessing individual elements like this works, however much of the time we won't actually know what index we need. In this situation, we can use the indexOf method to search the array for something we want, and it will return either the index, or -1
if not found.
For example
const list: string[] = [
"apples",
"bread",
"grapes"
];
const bread = list.indexOf("bread");
// 1
const soup = list.indexOf("soup");
// -1
Now that we've covered some methods to access individual elements, let's take a look at accessing all of the elements within an array using a for
loop.
for
loops come in two variants:
The C-style loop uses a counter and accesses each element using the techniques we previously covered.
For example
const nums: number[] = [1, 2, 3];
// C-style `for `loop
for (let i = 0; i < nums.length; i++) {
// access the element at index `i`
console.log(nums[i]);
}
Whereas, the for
loop using iteration is a bit more concise and we don't need to keep track of anything:
// iteration
for (const n of nums) {
console.log(n);
}
Both of these yield the same result, but it's preferable to use iteration in TypeScript because it automatically handles the counter and the element retrieval.
Anything can be stored in an array, including objects.
With that in mind, accessing data in a single object looks like this:
// shape of our object
interface LineItem {
name: string;
quantity: number;
}
// make an object
const bread = { name: "bread", quantity: 1 };
// get the total amount of bread
const total = bread.quantity;
But, to access this object when it exists in the array, we first need to locate the object.
We can work with it as we did previously:
// (Using the interface from above)
const bread = { name: "bread", quantity: 1 };
// put the bread into an array
const groceries: LineItem[] = [bread];
// get the total quantity of bread
const amount = bread[0].quantity;
// get the total quantities of all groceries
for (const item of groceries) {
console.log(item.quantity);
}
Finally we have nested arrays or 'an array of arrays'.
As you might have already guessed, since arrays can contain anything, then they can also contain arrays!
An array of arrays seems to be a common stumbling point for people, so let's look at an example, and how to access it.
For example
Imagine we have an array of students, and each student has an array of classes they are attending:
interface Section {
title: string;
}
interface Student {
name: string;
// Each student has an array of sections/classes
sections: Section[];
}
const william: Student = {
name: "William",
sections: [
{ title: "CS120" },
{ title: "HIST190" },
{ title: "MATH230" },
]
};
const wendy: Student = {
name: "Wendy",
sections: [
{ title: "CS140" },
{ title: "LIT200" },
{ title: "PHYS180" },
]
};
// Now we have an array of students
const students: Student[] = [william, wendy];
Just like the arrays and objects example, accessing the inner array requires first accessing the outer element:
// Type annotation not required because TypeScript already
// knows it's an array of Section because of the interface.
const sections = students[0].sections;
// get data for a single student
console.log("William's classes:");
for (const section of sections) {
console.log(`${section.title}`);
}
// looping over all students:
for (const student of students) {
console.log(`${student.name}'s classes:'`);
for (const section of student.sections) {
console.log(`${section.title}`);
}
}
Simple!
As you can see, arrays are an incredibly helpful tool for when you want to work with sequential data.
We've only scratched the surface here of available array methods, but it's enough of an introduction for you to try them out in your own code, and then dive deeper later on.
Speaking of which, if you struggled to grasp some of the concepts around arrays and how to use them, or just want a deeper dive into TypeScript, then check out my complete course on Typescript here.
You can even watch the first few lectures here for free.
The best part? When you join, you'll have direct access to me, other students, as well as full-time TypeScript devs in our private Discord channel - so you'll never be stuck!
If you've made it this far, you're clearly interested in TypeScript so definitely check out all of my TypeScript posts and content: