- TypeScript Tutorial
- TypeScript Home
- TypeScript Introduction
- TypeScript Setup
- TypeScript First Program
- TypeScript vs JavaScript
- TypeScript Data Types
- TypeScript Type Inference
- TypeScript Type Annotations
- TypeScript Interfaces
- TypeScript Enums
- TypeScript Type Aliases
- TypeScript Type Assertions
- TypeScript Variables
- TypeScript Functions
- TypeScript Functions
- TypeScript Optional Parameters
- TypeScript Default Parameters
- TypeScript Rest Parameters
- TypeScript Arrow Functions
- Classes and Objects
- Introduction to Classes
- Properties and Methods
- Access Modifiers
- Static Members
- Inheritance
- Abstract Classes
- Interfaces vs Classes
- Advanced Types
- TypeScript Union Types
- TypeScript Intersection Types
- TypeScript Literal Types
- TypeScript Nullable Types
- TypeScript Type Guards
- TypeScript Discriminated Unions
- TypeScript Index Signatures
- TypeScript Generics
- Introduction to Generics
- TypeScript Generic Functions
- TypeScript Generic Classes
- TypeScript Generic Constraints
- TypeScript Modules
- Introduction to Modules
- TypeScript Import and Export
- TypeScript Default Exports
- TypeScript Namespace
- Decorators
- Introduction to Decorators
- TypeScript Class Decorators
- TypeScript Method Decorators
- TypeScript Property Decorators
- TypeScript Parameter Decorators
- Configuration
- TypeScript tsconfig.json File
- TypeScript Compiler Options
- TypeScript Strict Mode
- TypeScript Watch Mode
Static Members in TypeScript
In TypeScript, static members (properties and methods) belong to the class definition itself rather than to specific instances of that class. Usually, when you create a class, you have to use the new keyword to create an object before you can access its properties. However, static members are available immediately on the class "blueprint."
This is incredibly useful when you want to share data across every instance of a class or when you have utility functions that don't need to maintain any internal state from an object.
Key Points About Static Members:
- Static members are declared using the
statickeyword. - They are accessed via the Class Name (e.g.,
MyClass.myStaticProp), not throughthisor an instance. - Static methods cannot access instance properties (non-static properties) because the instance might not even exist when the static method is called.
- They are great for memory efficiency because they exist in only one place in memory, regardless of how many objects you instantiate.
Declaring Static Properties
Static properties are often used for constants, configurations, or counters that need to be tracked across all objects of the same type.
Example:
class AppConfig {
static readonly API_URL: string = "https://api.example.com";
static sessionCount: number = 0;
constructor() {
AppConfig.sessionCount++;
}
}
// Accessing without creating an instance
console.log(AppConfig.API_URL); // Output: "https://api.example.com"
const user1 = new AppConfig();
const user2 = new AppConfig();
console.log(AppConfig.sessionCount); // Output: 2
In this example:
API_URLis a static read-only property. Every part of your app can see the URL without needing to create a newAppConfigobject.- The
sessionCountacts as a global counter for every time the class is instantiated.
this.propertyName inside the constructor. In TypeScript, you must use ClassName.propertyName.
Declaring Static Methods
Static methods are functions tied to the class. They are perfect for "Utility" or "Helper" classes where you don't need to store data, just perform a calculation or a transformation.
Example:
class Geometry {
static calculateArea(radius: number): number {
return Math.PI * radius * radius;
}
static calculateCircumference(radius: number): number {
return 2 * Math.PI * radius;
}
}
// No need to do: const geo = new Geometry();
console.log(Geometry.calculateArea(5)); // Output: 78.53...
In this example:
- The
Geometryclass acts as a container for related logic. Since the area of a circle doesn't change based on "which" geometry object you have, these methods are logically static.
Static Members and Instance Members
It is important to understand that the "Static world" and the "Instance world" are separate. An instance can look "up" at the class to see static members, but the class cannot look "down" at instances.
Example:
class User {
static totalUsers: number = 0; // Static
username: string; // Instance
constructor(username: string) {
this.username = username;
User.totalUsers++;
}
// Static method
static displayCount() {
console.log(`Total users: ${User.totalUsers}`);
// console.log(this.username); // ERROR: 'this' refers to the Class, not an instance.
}
// Instance method
describe() {
console.log(`This user is ${this.username}. There are ${User.totalUsers} total users.`);
}
}
const u1 = new User("Alice");
u1.describe(); // Works: Instance methods can access static properties.
User.displayCount(); // Works: Called on the class.
B extends class A, B.staticMethod() will work. However, this can sometimes lead to confusion regarding which class "owns" the data if the property is modified.
Static Initialization
Sometimes, initializing a static property requires more than a single line of code (like setting up a database connection or complex logic). TypeScript supports static blocks for this purpose.
Example:
class Database {
static connectionString: string;
// Static initialization block
static {
const env = "PRODUCTION";
if (env === "PRODUCTION") {
this.connectionString = "https://prod.db.com";
} else {
this.connectionString = "http://localhost:5432";
}
console.log("Database class initialized.");
}
}
console.log(Database.connectionString);
In this example:
- The
static {}block runs exactly once when the class is loaded, allowing for complex setup logic before the class is ever even used by the rest of your code.
Summary
Static members in TypeScript provide a way to define data and behavior that belongs to the class itself, offering a clean way to organize utility functions and shared state.
- Static properties: Shared across all instances; useful for constants and counters.
- Static methods: Called on the class; ideal for helper functions and factory patterns.
- Separation: Remember that static methods do not have access to
this(the instance), only to other static members.
By using static members appropriately, you reduce memory overhead and make your intent clear to other developers: "This logic belongs to the category, not a specific object."