Note: If you're new to TypeScript, check our Getting Started with TypeScript tutorial first.
In TypeScript, the static keyword is used to create static properties and methods. 
Static properties and methods belong to the class itself, and not to any individual instances of the class. In other words, they are shared among all instances of the class.
Static properties and methods are useful for data or behavior that is common to all instances.
TypeScript Static Properties
To create a static property, we use the static keyword before the property name. For example,
class Dog {
    // Declare a static property
    static bark: string = "Woof!";
    constructor(private name: string, private owner: string) {}
    
    dogIntro(): string {
        return `${this.name} loves its owner, ${this.owner}, and says ${Dog.bark}`;
    }
}
// Create instances of Dog class
let dog1 = new Dog("Wolfie", "Jessica");
let dog2 = new Dog("Honey", "James");
console.log(dog1.dogIntro());
console.log(dog2.dogIntro());
// Access the static property outside the class
console.log(`All dogs say ${Dog.bark}`);
Output
Wolfie loves its owner, Jessica, and says Woof! Honey loves its owner, James, and says Woof! All dogs say Woof!
Here, we have created a static property bark inside the Dog class. Thus, a single copy of bark is shared by all instances of Dog.
On the other hand, each instance of Dog will have its own copy of non-static properties and methods, i.e., name, owner, and dogIntro().
	Static Properties Are Accessed Using the Class Name
In the previous example, notice how the static property is accessed both inside and outside the class:
class Dog {
    ... ... ...
    // Access the static property inside the class    
    dogIntro(): string {
        return `${this.name} loves its owner, ${this.owner}, and says ${Dog.bark}`;
    }
}
... ... ...
// Access the static property outside the class
console.log(`All dogs say ${Dog.bark}`);
Usually, we use this to access non-static properties inside the class, while we use the object name (dog1 or dog2) to access those properties outside the class.
However, we use the class name to access static properties since they belong to the class itself, rather than to individual instances of the class:
// Valid way to access static property
Dog.bark
// Invalid ways to access static property (inside class)
this.bark
// Invalid ways to access static property (outside class)
dog1.bark
dog2.bark
Note: You can use this to access static properties inside a static method. 
Example 1: TypeScript Static Properties
class Employee {
    static headcount: number = 0; // Static property
    constructor(private name: string, private jobTitle: string) {
        // Increment headcount whenever a new instance is created
        Employee.headcount++;
    }
    
    getInfo(): void {
        console.log(`Employee: ${this.name}`);
        console.log(`Job Title: ${this.jobTitle}\n`);
    }
}
let employee1 = new Employee("John Doe", "Developer");
let employee2 = new Employee("Jane Doe", "Designer");
// Print the employee details
employee1.getInfo();
employee2.getInfo();
// Print the static property
console.log(`Headcount: ${Employee.headcount}`);
Output
Employee: John Doe Job Title: Developer Employee: Jane Doe Job Title: Designer Headcount: 2
In this program, we've created a static property headcount that is incremented each time we create an instance of the Employee class.
Initially, the value of headcount is 0.
And since we then proceeded to create two Employee instances (employee1 and employee2), the final value of headcount is 2.
TypeScript Static Methods
Like static properties, static methods belong to the class itself rather than to individual instances.
To create a static method, we use the static keyword before the method name. For example,
class Dog {
    private static bark: string = "Woof!";
    constructor(private name: string, private owner: string) {}
    
    dogIntro(): string {
        return `${this.name} loves its owner, ${this.owner}, and says ${Dog.bark}`;
    }
    // Create a static method that returns the static property
    static getBark(): string {
        return Dog.bark;
    }
}
// Create instances of Dog class
let dog1 = new Dog("Wolfie", "Jessica");
let dog2 = new Dog("Honey", "James");
console.log(dog1.dogIntro());
console.log(dog2.dogIntro());
// Access the static method
let dogBark: string = Dog.getBark();
console.log(`All dogs say ${dogBark}`);
Output
Wolfie loves its owner, Jessica, and says Woof! Honey loves its owner, James, and says Woof! All dogs say Woof!
Here, the static method getBark() returns the value of the private static property bark.
Outside the class, we accessed the static method by using the class name instead of the objects dog1 or dog2:
// Access the static method
let dogBark: string = Dog.getBark();
Example 2: TypeScript Static Methods
class Circle {
    // Static constant
    static readonly PI: number = 3.14159;
    static calculateArea(radius: number): number {
        return Circle.PI * radius * radius;
    }
}
// Access static property
console.log(`Value of PI: ${Circle.PI}`);
// Access static method
let area: number = Circle.calculateArea(5);
console.log(`Area of Circle: ${area}`);
Output
Value of PI: 3.14159 Area of Circle: 78.53975
Here, PI is a static constant, and calculateArea() is a static method. Thus, they're both shared by all instances of the Circle class.
Note: We use the readonly access modifier to declare class properties as constants. On the other hand, the const keyword is used to declare normal variables as constants.
More on TypeScript static
Since static properties and methods belong to the class itself, they don't depend on the existence of class instances.
As a result, they can be accessed even if you haven't created any instance of the class. For example,
class Dog {
    static bark: string = "Woof!";
    constructor(private name: string, private owner: string) {}
    
    dogIntro(): string {
        return `${this.name} loves its owner, ${this.owner}.`;
    }
    // Use 'this' inside a static method
    static getBark(): string {
        return Dog.bark;
    }
}
// Access static property
console.log(`Say ${Dog.bark}`);
// Access static method
let dogBark: string = Dog.getBark();
console.log(`All dogs say ${dogBark}`);
Output
Say Woof! All dogs say Woof!
Here, we accessed the static property and method without creating any instance of Dog.
However, we cannot access non-static properties and methods without creating an instance.
// Error: Property 'dogIntro' does not exist on type 'typeof Dog'.
console.log(Dog.dogIntro());
1. 'this' in Non-Static Methods
When you use this inside non-static methods, it refers to the individual instance of the class. For example,
class Dog {
    constructor(private name: string, private owner: string) {}
    
    dogIntro(): string {
        return `${this.name} loves its owner, ${this.owner}.`;
    }
}
let dog1 = new Dog("Wolfie", "Jessica");
let dog2 = new Dog("Honey", "James");
console.log(dog1.dogIntro());
console.log(dog2.dogIntro());
// Output:
// Wolfie loves its owner, Jessica.
// Honey loves its owner, James.
When dog1 is created.
this.namerefers todog1.name.this.ownerrefers todog1.owner.
When dog2 is created.
this.namerefers todog2.name.this.ownerrefers todog2.owner.
2. 'this' in Static Methods
However, inside static methods, this refers to the class itself, and not to any individual instances. For example,
class Dog {
    private static bark: string = "Woof!";
    constructor(private name: string, private owner: string) {}
    
    dogIntro(): string {
        return `${this.name} loves its owner, ${this.owner}.`;
    }
    // Use 'this' inside a static method
    static getBark(): string {
        return this.bark;
    }
}
let dog1 = new Dog("Wolfie", "Jessica");
let dog2 = new Dog("Honey", "James");
console.log(dog1.dogIntro());
console.log(dog2.dogIntro());
let dogBark: string = Dog.getBark();
console.log(`All dogs say ${dogBark}`);
Output
Wolfie loves its owner, Jessica. Honey loves its owner, James. All dogs say Woof!
Here, we've used this inside the static method getBark():
static getBark(): string {
    return this.bark;
}
In this case, it doesn't matter what or how many instances of Dog you create. In all cases, this.bark will always refer to Dog.bark since it's used inside a static method.
Static methods can't access non-static properties because non-static properties belong to individual instances of a class.
As such, non-static properties don't come into existence until an object is created. For example,
class Dog {
    // Non-static property
    breed: string;
    constructor(breed: string) {
        this.breed = breed;
    }
    // Static method
    static getBreed(): void {
    
        // Error because getBreed() is static but breed is not
        console.log(this.breed);
    }
}
Here, the static method getBreed() cannot access the non-static property breed because this inside static methods refers to the class and not to the instance of the class.
However, breed (as a non-static property) belongs to class instances. Thus, getBreed() is unable to access it.
While static methods cannot access non-static properties, non-static methods can easily access static properties. For example,
class Dog {
    // Declare a static property
    static bark: string = "Woof!";
    constructor(private name: string, private owner: string) {}
    
    // Non-static method that accesses
    // both static and non-static properties
    dogIntro(): string {
        return `${this.name} loves its owner, ${this.owner}, and says ${Dog.bark}`;
    }
}
let dog1 = new Dog("Wolfie", "Jessica");
console.log(dog1.dogIntro());
// Output: Wolfie loves its owner, Jessica, and says Woof!
Here, the non-static dogIntro() method is able to access the static property bark.
It's because instance methods have access to this (the instance) and can also access static members using the class name (Dog.bark).
This is allowed because static members are accessible on the class itself.
Read More: