Question
In TypeScript, an array type for a property or variable can be written in two common ways:
let prop1: Array<string>;
let prop2: string[];
You can also use custom types:
let users1: Array<MyType>;
let users2: MyType[];
What is the difference between Array<Type> and Type[] in TypeScript? Are they equivalent, or do they behave differently? I may also be confusing the angle bracket syntax (<>) with type casting or another TypeScript feature.
Short Answer
By the end of this page, you will understand that Array<Type> and Type[] usually represent the same array type in TypeScript. You will learn how the two syntaxes work, when one may be easier to read than the other, how they relate to generics, and which style developers often choose in real projects.
Concept
In TypeScript, both Array<Type> and Type[] describe an array whose elements all have the same type.
For example, these mean the same thing:
let names: string[];
let otherNames: Array<string>;
Both variables are arrays of strings.
Why there are two syntaxes
TypeScript supports:
- Bracket array syntax:
Type[] - Generic array syntax:
Array<Type>
The Array<Type> form uses a generic type. Array is a built-in generic type, and the type inside angle brackets tells TypeScript what kind of values the array contains.
So this:
Array<string>
means:
- use the generic
Array - fill in
stringas the element type
The shorter form:
string[]
is just alternative syntax for the same idea.
Why this matters
Understanding this helps you:
- read different TypeScript codebases
- understand generic types better
- write clearer type annotations
- avoid confusion between array syntax and angle-bracket type syntax
About the angle brackets
In Array<string>, the <string> part is not a cast. It is a generic type argument.
It tells TypeScript:
- this is an
Array - each item inside it is a
string
That is different from older angle-bracket type assertions like:
let value = <string>someUnknownValue;
Those assertions exist in TypeScript, but they are a different feature. In modern TypeScript, developers often prefer as for type assertions:
let value = someUnknownValue as string;
So in your question, Array<string> is about declaring an array type, not casting.
Mental Model
Think of an array as a box that holds many items of the same kind.
string[]means: a box full of stringsArray<string>means: an array box configured to hold strings
These are two labels for the same kind of box.
Another way to think about it:
Type[]is the shorthandArray<Type>is the generic form
Just like two routes leading to the same destination, both describe the same resulting type.
Syntax and Examples
Basic syntax
let a: string[] = ["Alice", "Bob"];
let b: Array<string> = ["Alice", "Bob"];
Both variables are arrays of strings.
With custom types
type User = {
id: number;
name: string;
};
let usersA: User[] = [
{ id: 1, name: "Sam" },
{ id: 2, name: "Lee" }
];
let usersB: Array<User> = [
{ id: 3, name: "Ana" },
{ id: 4, name: "Max" }
];
Again, both forms mean the same thing.
Arrays of arrays
This is where readability can matter.
let grid1: number[][];
let grid2: Array<Array<number>>;
These are equivalent, but some people find one easier to read than the other.
Union example
When using union types, parentheses matter with Type[]:
let values1: (string | number)[] = ["a", 1, "b", 2];
let values2: Array<string | number> = ["a", 1, "b", 2];
These are equivalent.
Without parentheses, this means something different:
let onlyStringsOrNumbersArray: string | number[];
That means:
- either a single
string - or an array of
number
It does not mean an array containing both strings and numbers.
Function example
function printNames(names: string[]): void {
names.forEach((name) => console.log(name));
}
function printNamesGeneric(names: Array<string>): void {
names.forEach((name) => console.log(name));
}
Both function parameters have the same type.
Step by Step Execution
Consider this code:
let scores: number[] = [10, 20, 30];
scores.push(40);
let firstScore: number = scores[0];
console.log(firstScore);
Step by step
-
let scores: number[] = [10, 20, 30];- A variable named
scoresis created. - Its type is
number[], meaning an array of numbers. - The array starts with three values:
10,20, and30.
- A variable named
-
scores.push(40);- A new number is added to the array.
- This is allowed because
40is a number. - The array becomes
[10, 20, 30, 40].
-
let firstScore: number = scores[0];- The first element is read from the array.
scores[0]is10.- It is stored in
firstScore, which expects anumber.
-
console.log(firstScore);- The value
10is printed.
- The value
Now compare the same logic with Array<number>:
let scores: Array<number> = [10, 20, 30];
Everything else behaves the same. Only the type syntax is different.
Real World Use Cases
Developers use typed arrays constantly in TypeScript projects.
Common examples
- API responses
User[]for a list of users returned from a server
- Form validation
string[]for validation error messages
- UI rendering
Product[]for rendering product cards in a list
- Data processing
number[]for scores, prices, or measurements
- Configuration
Array<string>for supported locales or feature flags
Example: API data
type Post = {
id: number;
title: string;
};
function renderPosts(posts: Post[]): void {
posts.forEach((post) => {
console.log(post.title);
});
}
Example: error collection
function validatePassword(password: string): string[] {
const errors: string[] = [];
if (password.length < 8) {
errors.push("Password must be at least 8 characters.");
}
return errors;
}
Real Codebase Usage
In real TypeScript codebases, both forms appear, but teams usually pick one style and use it consistently.
Common team preferences
- Many developers prefer
Type[]for simple arrays because it is short and easy to scan. - Some prefer
Array<Type>because it matches other generic types likePromise<Type>orMap<Key, Value>.
Patterns in real projects
Function parameters
function saveUsers(users: User[]): void {
// ...
}
Return types
function getIds(): Array<number> {
return [1, 2, 3];
}
Readonly arrays
Developers often use readonly Type[] or ReadonlyArray<Type> when an array should not be changed.
function printTags(tags: readonly string[]): void {
tags.forEach((tag) => console.log(tag));
}
function printTags(tags: ReadonlyArray<string>): void {
tags.forEach((tag) => console.log(tag));
}
Validation and transformation
Typed arrays are often combined with:
map()to transform itemsfilter()to remove itemsfind()to locate one item- guard clauses to validate input early
function getActiveNames(users: User[]): string[] {
return users
.filter((user) => user.active)
.map((user) => user.name);
}
Practical advice
Use one style consistently in a project. Consistency usually matters more than which of the two forms you choose.
Common Mistakes
1. Thinking Array<Type> and Type[] are different types
They are usually the same.
let a: string[] = ["x", "y"];
let b: Array<string> = ["x", "y"];
Both are arrays of strings.
2. Confusing generic syntax with type assertions
This is a generic type:
let names: Array<string> = ["A", "B"];
This is a type assertion:
let value = someData as string;
Do not mix those ideas together.
3. Forgetting parentheses with unions
Broken meaning:
let values: string | number[];
This means:
- a
string - or a
number[]
If you want an array whose items can be either type, write:
let values: (string | number)[];
Or:
let values: Array<string | number>;
4. Mixing up array of union vs union of arrays
These are not the same:
let a: (string | number)[];
let b: string[] | number[];
acan contain both strings and numbers togetherbmust be either all strings or all numbers
5. Inconsistent style in the same file
This is valid, but can hurt readability:
let ids: number[] = [1, 2, 3];
let names: Array<string> = ["A", "B"];
Prefer a consistent convention unless there is a clear readability reason.
Comparisons
Type[] vs Array<Type>
| Syntax | Example | Meaning | Notes |
|---|---|---|---|
Type[] | string[] | Array of strings | Short and common |
Array<Type> | Array<string> | Array of strings | Generic style |
Equivalent examples
| This | Same as |
|---|---|
number[] | Array<number> |
User[] | Array<User> |
| `(string | number)[]` |
number[][] | Array<Array<number>> |
Related comparison: mutable vs readonly arrays
| Type | Example | Can modify? |
|---|---|---|
| Mutable array | string[] | Yes |
| Mutable array | Array<string> | Yes |
| Readonly array | readonly string[] | No |
| Readonly array | ReadonlyArray<string> | No |
When one may be clearer
- Use
Type[]when the element type is simple:string[],User[] - Use
Array<Type>when you want consistency with generics such asPromise<User> - For more complex nested or union types, choose whichever is easier to read
Cheat Sheet
// Equivalent array types
let a: string[];
let b: Array<string>;
// Custom types
type User = { id: number; name: string };
let users1: User[];
let users2: Array<User>;
// Union items
let mixed1: (string | number)[];
let mixed2: Array<string | number>;
// Nested arrays
let matrix1: number[][];
let matrix2: Array<Array<number>>;
// Readonly arrays
let tags1: readonly string[] = ["ts", "js"];
let tags2: ReadonlyArray<string> = ["ts", "js"];
Rules to remember
Type[]andArray<Type>are usually equivalent.Array<Type>uses generic syntax.<>inArray<string>is not casting.- Use parentheses with unions in
Type[]syntax:(A | B)[] - Be consistent with style in a codebase.
Easy choices
- Simple arrays:
string[] - Generic-style consistency:
Array<string> - Readonly arrays:
readonly string[]orReadonlyArray<string>
FAQ
Is Array<string> the same as string[] in TypeScript?
Yes. In normal TypeScript usage, they describe the same type: an array of strings.
Which is better: Array<Type> or Type[]?
Neither is more correct. Most teams choose one based on readability and consistency.
Does Array<string> use casting?
No. The <string> part is a generic type argument, not a cast.
When should I use parentheses with Type[]?
Use parentheses when the element type is a union, such as (string | number)[].
Is string | number[] the same as (string | number)[]?
No. string | number[] means either a single string or an array of numbers. (string | number)[] means an array containing strings, numbers, or both.
Are readonly arrays different?
Yes. readonly string[] and ReadonlyArray<string> prevent array modification through that reference.
Why do I see both styles in real projects?
Because both are valid. Different teams, style guides, and developers prefer different syntax.
Mini Project
Description
Create a small TypeScript module that stores and prints a list of products. The project demonstrates that Product[] and Array<Product> can both be used to describe arrays of objects, and shows how typed arrays make iteration and property access safer.
Goal
Build a typed product list and print formatted product information using both array syntaxes.
Requirements
- Define a
Producttype withid,name, andpriceproperties. - Create one product list using
Product[]. - Create another product list using
Array<Product>. - Write a function that accepts a typed array of products and logs each product.
- Show that both array declarations work with the same function.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Accessing Input Value from EventTarget in TypeScript
Learn why EventTarget has no value property in TypeScript and safely read values from HTML input events in Angular applications.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.