Question
I am building a simple logic game called “Three of a Crime” in TypeScript. How can I create an empty array that is typed to contain Criminal objects?
I tried:
var arr = Criminal[];
This produced the error: Check format of expression term.
I also tried:
var arr: Criminal = [];
This produced an error because an empty array cannot be assigned to a single Criminal value. What is the correct TypeScript syntax for creating an empty typed array?
Short Answer
You will learn how TypeScript distinguishes one object from an array of objects, how to initialize an empty typed array, and how to safely create arrays with an intended size.
Concept
Criminal means one value whose type is Criminal.
Criminal[] means an array whose elements are Criminal values.
To create an empty typed array, put the array type after the variable name and assign an array value:
const criminals: Criminal[] = [];
The : Criminal[] part is a type annotation. It tells TypeScript what may be stored in the array. The [] part is an array expression: it creates an empty array at runtime.
This distinction matters because TypeScript types are mostly checked during development and then removed when JavaScript is produced. At runtime, JavaScript needs an actual value such as []; it cannot execute a type like Criminal[].
Mental Model
Think of Criminal as the label for one evidence folder.
Criminal[] is the label for a storage box that may hold many evidence folders.
const criminal: Criminal = ...expects one folder.const criminals: Criminal[] = []creates an empty box for folders.
Writing Criminal[] by itself is only a label describing a kind of box. It is not the box itself. To create the box, use [].
Syntax and Examples
Use either Type[] or the generic Array<Type> syntax.
interface Criminal {
name: string;
motive: string;
}
const criminals: Criminal[] = [];
criminals.push({ name: "Alex", motive: "Money" });
criminals.push({ name: "Blair", motive: "Revenge" });
console.log(criminals);
criminals starts empty, but TypeScript permits only values matching the Criminal shape.
criminals.push({ name: "Casey" });
// Error: Property 'motive' is missing.
The equivalent generic form is:
const criminals: <> = [];
Step by Step Execution
Consider this code:
interface Criminal {
name: string;
motive: string;
}
const suspects: Criminal[] = [];
suspects.push({ name: "Morgan", motive: "Jealousy" });
const firstSuspect = suspects[0];
console.log(firstSuspect.name);
- The
interfacedefines the required shape of aCriminal. const suspects: Criminal[] = []creates an empty JavaScript array and records that it should containCriminalobjects.pushadds an object with both required properties, so TypeScript accepts it.suspects[0]reads the first object from the array.- The program prints
Morgan.
With noUncheckedIndexedAccess enabled in tsconfig.json, TypeScript treats as possibly , because an array index may not exist. Check it before using it:
Real World Use Cases
Typed arrays are useful whenever a program collects multiple values of one kind:
- Game state: store suspects, clues, cards, turns, or board cells.
- API data: represent a list returned from
/usersor/orders. - Form validation: collect validation messages as
string[]. - Data processing: build a
Transaction[]while reading a file or database rows. - UI rendering: store
Product[]and render one item per product.
Example: collecting validation errors.
const errors: string[] = [];
if (!email.includes("@")) {
errors.push("Enter a valid email address.");
}
if (password.length < 8) {
errors.push("Password must contain at least 8 characters.");
}
Real Codebase Usage
In real projects, typed arrays commonly appear as function return types, object properties, and API models.
Return a list from a function
function findSuspiciousCriminals(criminals: Criminal[]): Criminal[] {
return criminals.filter((criminal) => criminal.motive !== "None");
}
Store an initially empty list in application state
class GameState {
readonly clues: string[] = [];
}
readonly prevents replacing the property with another array, though items can still be added to the existing array.
Validate before adding data
function addCriminal(list: Criminal[], criminal: Criminal): void {
if (criminal.name.trim() === ) {
();
}
list.(criminal);
}
Common Mistakes
Using an element type instead of an array type
const criminals: Criminal = [];
This is incorrect because criminals is declared as one Criminal, but [] is an array.
const criminals: Criminal[] = [];
Treating a type as a runtime value
const criminals = Criminal[];
This is invalid. Criminal[] describes a type and cannot create an array. Use an array literal:
const criminals: Criminal[] = [];
Omitting the type when the empty array needs a known element type
const criminals = [];
The inferred type for an empty array can be too broad or depend on compiler settings and later usage. Add an annotation when the intended element type is known:
Comparisons
| Syntax | Meaning | When to use it |
|---|---|---|
Criminal | One criminal object | A variable holds exactly one object |
Criminal[] | An array of criminal objects | The usual array syntax |
Array<Criminal> | An array of criminal objects | Equivalent generic syntax; useful for complex types |
[] | An empty array value | Runtime initialization |
new Array<Criminal>(n) | Array with n empty slots | Rarely appropriate; it does not create objects |
| `Array<Criminal | undefined>` | Array whose positions may be empty |
Cheat Sheet
// Empty typed array
const items: Criminal[] = [];
// Equivalent generic syntax
const items: Array<Criminal> = [];
// Add a valid item
items.push({ name: "Alex", motive: "Money" });
// Function parameter and return type
function copy(items: Criminal[]): Criminal[] {
return [...items];
}
// Create actual values with a factory
const items: Criminal[] = Array.from({ length: 3 }, (_, i) => ({
name: `Suspect ${i + 1}`,
motive: "Unknown"
}));
// Slots that may be unfilled
const slots: Array<Criminal | undefined> = ().();
FAQ
How do I declare an empty array of objects in TypeScript?
Use an array type annotation and an empty array literal:
const criminals: Criminal[] = [];
Is Criminal[] the same as Array<Criminal>?
Yes. Both describe an array whose elements are Criminal. Criminal[] is usually more concise.
Why does const item: Criminal = [] fail?
Criminal describes one object, while [] is an array. Use Criminal[] for an array.
Can I use var instead of const?
You can, but const is usually preferred when the variable should always refer to the same array. You can still call push on a const array.
How do I preallocate an array in TypeScript?
For a fixed number of real initial values, use with a factory function. Avoid unless you specifically want empty slots.
Mini Project
Description
Create a small suspect roster for a crime-solving game. The roster begins as an empty typed array, accepts valid suspect objects, and produces a filtered list of suspects who have a known motive.
Goal
Build and use a Criminal[] array without allowing incorrectly shaped objects.
Requirements
- Define a
Criminalinterface withnameandmotiveproperties. - Create an empty array typed as
Criminal[]. - Add at least three valid criminals to the array.
- Filter the array to find criminals whose motive is not
"Unknown". - Print each matching suspect's name and motive.
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.