Skip to Content
Course content

175: The Array Type Syntax T[] vs Array<T>

Click on the "Edit" button in the top corner of the screen to edit your slide content.

You’ve probably noticed that in TypeScript, there are two ways to tell the compiler you're dealing with a list of things. You can use the shorthand T[] syntax, or you can use the generic Array<T> syntax. If you look at the official documentation, they'll tell you they are functionally identical. The compiler doesn't care which one you pick; the resulting JavaScript is exactly the same.

But in a real-world codebase, consistency is everything. I often see developers—especially those coming from Java or C#—default to Array<T> because it feels more "explicit" and aligns with how they handle other generics like Maps or Sets. It looks like this:

type UserRole = 'admin' | 'editor' | 'viewer';

function assignPermissions(roles: Array<UserRole>) {
  // logic here
}

Now, this isn't "wrong," but it is noisy. When I'm reviewing a pull request, my eyes have to parse those angle brackets every single time. Compare that to the shorthand:

function assignPermissions(roles: UserRole[]) {
  // logic here
}

The visual tax of angle brackets

I always push my team toward T[]. Why? Because it's a quicker scan. When you're looking at a complex function signature with five or six arguments, string[] and number[] blend into the background, letting you focus on the actual logic. Array<string> draws more attention to the container than the content. Unless you have a very specific reason to use the generic syntax, the shorthand is the industry standard for a reason: it reduces cognitive load.

Where the shorthand gets tricky

There is one specific spot where the shorthand can trip you up, and it's usually where "naive" TypeScript starts to break. I'm talking about union types. Let's say you have a list that can contain either strings or numbers. If you write this:

const mixedData: string | number[] = ['hello', 1, 2];

You've just created a bug. You didn't tell TypeScript you have an array of strings-or-numbers; you told it that the variable mixedData is either a single string OR an array of numbers. The compiler will scream at you the moment you try to treat mixedData as an array because it might just be a string.

To fix this with shorthand, you have to wrap the union in parentheses: (string | number)[]. At this point, I'll admit that Array<string | number> actually looks a bit cleaner. The angle brackets act as natural boundaries, making it obvious that the union is the type being stored in the array. I occasionally use the generic syntax for these complex types just to avoid the "parentheses soup," but for 95% of your arrays, T[] is the way to go.

Choosing your baseline

My advice is to pick a baseline and stick to it. Mixing string[] and Array<string> in the same file is a sign of a codebase that hasn't been curated. If you're working on a project that already uses Array<T>, follow the existing pattern. But if you're starting fresh, go with T[]. It's leaner, faster to read, and it's what most of the TypeScript ecosystem expects to see.




📋 Practical Task

Refactoring the Project Access Control List

You've inherited a module for managing project permissions. The current code is inconsistently typed and contains a logic error where a union type array was declared incorrectly, causing the compiler to think the variable is a single string rather than a list of identifiers.

Your Task: Refactor the following code to use the T[] shorthand consistently throughout. Then, fix the authorizedIds type declaration so that it correctly represents an array that can hold either strings or numbers.

type Identifier = string | number;
type Permission = 'read' | 'write' | 'execute';

interface ProjectConfig {
  projectName: string;
  // FIX THIS: This is currently typed as "a string OR an array of numbers"
  authorizedIds: Identifier | number[]; 
  // REFACTOR THIS: Use the shorthand syntax
  permissions: Array<Permission>;
}

function validateAccess(config: ProjectConfig, userIds: Array<Identifier>): boolean {
  return config.authorizedIds.includes(userIds[0]);
}
Rating
0 0

There are no comments for now.

to be the first to leave a comment.