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