Write TypeScript like a pro. Typescript Icon

Follow the ultimate TypeScript roadmap.

Typing Arrays in TypeScript

There are many ways in TypeScript to type a property as an array, or contains an array of “something”. These ways of declaring an array type include generic types, array types and type assertions - which we’ll uncover in this article.

We’ll use a class to demonstrate how we can declare some of these properties as well to demonstrate the various ways.

Type Inference

Before we explore the benefits of explicit typing, let’s consider a class with an array.

This will infer the type of an array in TypeScript:

// inferred as messages: any[]
class Chats {
  messages = [];
}

Inferring a type means that TypeScript has some kind of knowledge about your type, and supplies it to you to use. By using [] we allow TypeScript to infer the any[] type to the compiler.

If we change the type to include numbers, TypeScript picks this up too (number[]):

// inferred as messages: number[]
class Chats {
  messages = [1, 2, 3];
}

We can of course mix and match our types, and TypeScript will infer as best as possible:

// inferred as messages: (string | number)[]
class Chats {
  messages = ['A', 'B', 1, 2];
}

This is great for well defined APIs, return statements and such that we are fully confident we want to infer. For example a third-party library code could ship with library definitions. Using their API will infer the type if they’ve supplied type definitions.

So let’s explore the main ways we can type an array in TypeScript.

Angular Directives In-Depth eBook Cover

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.

  • Green Tick Icon Observables and Async Pipe
  • Green Tick Icon Identity Checking and Performance
  • Green Tick Icon Web Components <ng-template> syntax
  • Green Tick Icon <ng-container> and Observable Composition
  • Green Tick Icon Advanced Rendering Patterns
  • Green Tick Icon Setters and Getters for Styles and Class Bindings

Declaring an Array Type

Let’s introduce a second class member of Message:

class Message {
  constructor(private sender: string, private message: string) {}
}

// create a new message
new Message('Todd Motto', 'Hey, you around?');

Our Chats example class can now be typed like so:

class Chats {
  messages: Message[] = [];
}

We assign what looks like an array, but we know it’s a type as we’re using : before the array assignment. Interestingly, outside of the array [] type, we specify what the array contains, i.e. Message[].

Learn more about using Classes as Types!

In this case, we’re expecting only an array of messages. We could in fact just declare the properties on the class, and assign the property’s value perhaps in the constructor:

class Chats {
  messages: Message[];

  constructor() {
    this.messages = [];
  }
}

In Angular for example, this is typically done inside the ngOnInit lifecycle hook:

class Chats implements OnInit {
  messages$: Observable<Message[]>;

  constructor(private store: Store<State>) {}

  ngOnInit() {
    this.messages$ = this.store.select('messages');
  }
}

A more comprehensive example, but we digress. However - you may have noticed Observable<Message[]>. Have you seen this before? If not, let’s explain because the same principle applies when typing arrays.

Using Array Generic Types

Generics are parameterised types, where we can either let TypeScript infer the type for us or specify it ourselves. Using a generic type in TypeScript alongside an array looks like this (which is the equivalent to what we’ve covered above):

class Chats {
  messages: Array<Message> = [];
}

There’s no functional difference between using a generic instead of a normal typing, however depending on your use case and complexity of types - you may wish to opt for one over the other.

Another nice thing about generics is that we can combine initialisation and also infer the type, creating a new array whilst passing the generic type:

// inferred as messages: Message[]
class Chats {
  messages = new Array<Message>();
}

I’d recommend using this approach to type an array in TypeScript:

class Chats {
  messages: Message[] = [];
}

It’s a more modern syntax and appears more like an array literal.

There are actually a few more ways to type an array as well, I’ve added some notes for you:

// Looks a little more oldschool, but same as above
class Chats {
  messages: Array<Message> = new Array();
}

// Don't do this unless you need to assert the type
class Chats {
  messages = [] as Message[];
}

// And really, don't do this
class Chats {
  messages = <Array<Message>>[];
}

As the saying goes, “A typed array keeps the errors away”…

If you are serious about your TypeScript skills, your next step is to take a look at my TypeScript courses, they will teach you the full language basics in detail as well as many advanced use cases you’ll need in daily TypeScript development!

Happy coding!

Learn TypeScript the right way.

The most complete guide to learning TypeScript ever built.
Trusted by 82,951 students.

Todd Motto

with Todd Motto

Google Developer Expert icon Google Developer Expert

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover