TypeScript Tutorial
TypeScript Static
static on a class member is shared by every object. Call it on the class name, not on an instance.
One copy for the class
static on a class member means there is one copy for the whole class, not one copy per object. Use it for a running total of how many objects exist, or a helper that does not need this. Call it on the class name: Guest.count, Guest.howMany().
C++ needs an out-of-class definition for a static data member in older standards. TypeScript stores the static field on the class as written. There is no second line int Guest::count = 0;.
A static field shared by every object
Put static count = 0 in the class. Every constructor reads and writes that same number. Ordinary fields still belong to each instance.
Example
class Guest {
static count = 0;
constructor() {
Guest.count++;
}
}
const a = new Guest();
const b = new Guest();
const c = new Guest();
console.log(Guest.count);Output is 3. Three constructors ran. There is still only one count.Guest.count is the usual way to read it. Reading a.count is not how this tutorial accesses statics; use the class name so the shared lifetime is obvious.
Compile at /typescript/try. Add a fourth new Guest() andGuest.count becomes 4.
A static method has no this
A method marked static can use static fields. It cannot use ordinary instance fields, because there may be no object. Call it on the class: Guest.howMany(). You can call it before any object exists.
Example
class Guest {
static count = 0;
constructor() {
Guest.count++;
}
static howMany(): number {
return Guest.count;
}
}
console.log(Guest.howMany());
const a = new Guest();
const b = new Guest();
console.log(Guest.howMany());Output is 0 then 2. The first call happens with no Guest objects at all. Inside howMany, write Guest.count, not this.count, so the method still reads clearly if you later refactor.
Instance data stays per object
Mix both. Each guest has a name. The class tracks how many guests were built. The constructor sets the instance field and bumps the static counter.
Example
class Guest {
static count = 0;
readonly name: string;
constructor(name: string) {
this.name = name;
Guest.count++;
}
}
const a = new Guest("Ada");
const b = new Guest("Linus");
console.log(a.name);
console.log(b.name);
console.log(Guest.count);Output is Ada, Linus, then 2. Names differ. The count is shared.
Class static versus a module-level const
| static member | const in the file | |
|---|---|---|
| Where you write it | Inside a class | Next to the class, or in a module |
| How many copies | One for the class | One for the file |
| How you call it | Guest.howMany() | A bare function name |
| Tied to the type | Yes | Only by convention |
Use a static member when the data belongs to the type. Use a module-level function when no class is involved. Neither is a substitute for passing arguments. Hidden counters make tests harder: the next call depends on every call that already happened.
Do not hide all state this way
For a tutorial counter, statics are clear. For application data, prefer an object you can construct, reset, and pass in. Next: abstract classes, where a base type cannot be constructed and you only build the derived types.