While traditional JavaScript programs use functions and prototype-based inheritance to create reusable components, starting with ES6, JavaScript programs are able to use a class-based object-oriented approach. With TypeScript, you can take advantage of the new features specified in ES6 and compile JavaScript to run on all major browsers and platforms.

Basic usage

class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)}}Copy the code

inheritance

An important rule that TypeScript enforces is to call super() before accessing the this property in the constructor.

class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)}}class SuperPerson extends Person {
  public name: string;
  constructor(love: string, name: string) {
    super(love);
    this.name = name;
  }
  public sayName(){
    console.log(`my name is ${this.name}`)}}let me = new SuperPerson('HTML'.'funlee');
me.sayLove()
me.sayName()
Copy the code

Access control

Public, private, protected

The default is public, so I won’t go over it again.

When a member is marked private, it is not accessible outside of the class in which it is declared, as is the case with protected properties.

class Person {
  private love: string; // or prot
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)}}let me = new Person('TS');
me.love = 'JS'; // error

Copy the code

Private differs from protected in that protected members are still accessible in derived classes. Such as:

class Person {
  protected name: string; 
  constructor(name: string) {
    this.name = name; }}class Man extends Person {
  private love: string;
  constructor(name: string, love: string) {
    super(name);
    this.love = love;
  }
  public say() {
    // If Person uses a private modifier for name, the name attribute cannot be accessed
    console.log(`my name is ${this.name}, and my love is ${this.love}`); }}let me = new Man('funlee'.'TS');

Copy the code

Note: TypeScript uses the structural type system, so when comparing two different types, they are compatible if all the member types are compatible. Such as:

class A {
  prop1: string
}
class B {
  prop1: string
  prop2: string
}
let instance:A = new B() // This is allowed because all member types of A are present in B

Copy the code

However, if the class being compared has private and protected members, the situation is different. In this case, the other class must also have the corresponding private or protected members for the types to be compatible.

class A {
  private prop1: string
}
class B {
  private prop2: string
}
let p1:A = new B() / / an error
class C extends A {

}
let p2:A = new C() // This is allowed

Copy the code

readonly

Properties can be set to read-only using the readonly keyword, which must be initialized at declaration time or in a constructor.

class Person {
  readonly name: string;
  constructor(name: string) {
    this.name = name; }}let me = new Person('funlee');
me.name = 'new name'; // error

Copy the code

Parameter properties

Parameter attributes allow members to be created and initialized at the same time. Declarations and assignments can be combined in one place, as in:

class Person {
  constructor(public name: string.protected love: string, readonly age: number.private weight: string) {
    this.name = name;
    this.love = love;
    this.age = age;
  }
  public sayWeight() {
    console.log(`my weight is ${this.weight}`)}}let me = new Person('funlee'.'TS'.18.'55kg');
me.sayWeight()

Copy the code

accessor

TypeScript supports getters and setters, but with one limitation: compiler output must be set to ES5 or higher, there is no support for downgrading to ES3, and when an accessor has only GET but no set, it is automatically inferred as readonly.

class Person {
  public _love: string;
  constructor(love: string) {
    this._love = love;
  }
  get love(): string{
    return this._love;
  }
  set love(newLove: string) {
    this._love = `error!! my love can't be chenged`; }}let me = new Person('TS');
console.log(me.love); // TS
me.love = 'HTML';
console.log(me.love); // error!! my love can't be chenged

Copy the code

Static attributes

We can use static to define static attributes of a class. Static attributes belong to the class itself, not to the instance.

class Person {
  static love: string = 'TS';
}
let me = new Person();
console.log(Person.love); // TS
console.log(me.love); // error

Copy the code

An abstract class

Abstract classes can only be used as base classes of other derived classes. Abstract classes cannot be instantiated. They have the following characteristics:

  • Abstract classes can contain implementation details of members, and abstract classes must be declared with abstract
  • Methods in an abstract class that do not contain a method body are called abstract methods. Methods that use abstract declarations must be implemented by subclasses (abstract methods must be declared using the abstract keyword and can contain access modifiers).
abstract class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  abstract sayLove(): string; // Must be implemented in a derived class
}
class Man extends Person{
  constructor(love: string) {super(love)
  }
  sayLove() {
    return `my love is ${this.love}`; }}let me = new Man('TS');
console.log(me.sayLove()); // my love is TS

Copy the code

Use classes as interfaces

A class definition creates two things: an instance type of the class and a constructor. Because classes can create types, they can use classes where interfaces are allowed.

class Person {
  name: string;
  age: number;
}
interface Man extends Person {
  love: string;
}
let me: Man = {
  name: 'funlee',
  age: 18,
  love: 'TS'
}

Copy the code