One: Know TS

Why learn TS

  1. TypeScript was developed by Microsoft

An open source programming language.

  1. TypeScript is the super version of Javascript and follows the latest ES6 and Es5 specifications. TypeScript extends JavaScript’s syntax.

  2. TypeScript is more like object-oriented languages such as backend Java and C# that allow js to develop large enterprise projects.

5. Google is also actively promoting Typescript. Google’s Angular2. x+ is based on Typescript syntax. The latest Versions of Vue3.0 and React also integrate with TypeScript.

TypeSc RIpt should be designed to address JavaScript “pain points” :

1. Weak typing and lack of namespaces make modularity difficult

2. Not suitable for developing large programs.

3. Provides some syntax candy to help you practice object-oriented programming more easily. (Classes, interfaces, enumerations, generics, method overloading, etc.)

  1. One of the cool things about TypeScript’s design is that it doesn’t throw out JavaScript syntax and start from scratch. Instead, it’s a superset of JavaScript (credit to Anders), so that any valid JavaScript statement is valid in TypeScript. That means learning is cheap

Ts compilation and installation

  1. npm install -g typescript
  2. TSC points to the file at the end of TS

Use Terminal in the vscode editor

  1. tsc –init
  2. Run Task

Select typescript 4. TSC: Watch

Two: the original data type of TS

JavaScript types are divided into two types: primitive data types and object types. Primitive data types include Boolean, numeric, string, NULL, undefined, and the new types [‘Symbol] and [BigInt] in ES6. This article focuses on the first five The use of primitive data types in TypeScript.

1: Boolean value

Booleans are the most basic data types. In TypeScript, Boolean is used to define Boolean types:

Let isDone: boolean = false; Note that objects created using constructor Boolean ** are not Boolean values: let createdByNewBoolean: Boolean = new Boolean (1); // New BooLean() returns a BooLean object let createdByNewBoolean: BooLean = new BooLean(1); // Call Boolean directly, return a Boolean type createdByNewBoolean Boolean = Boolean (1); CreatedByNewBoolean ='1,2,3'Copy the code

In TypeScript, Boolean is the basic type in JavaScript, and Boolean is the constructor in JavaScript. The other basic types (except null and undefined) are not mentioned here.

2: numerical

Define numeric types using number:

Let decliteral: number = 6;
Copy the code

Compile result:

var decLiteral = 6;
Copy the code

3: string

Use string to define a string type:

let myName: string = 'Tom';
let myAge: number = 25;
// Template string
let sentence: string = `Hello, my name is ${myName}I'll be ${myAge + 1} years old next month.`
Copy the code

Compile result:

var myName = 'Tom';
var myAge = 25;
// Template string
var sentence = "Hello, my name is" + myName + "I'll be"+ (myAge + 1) +"years old next month.";
Copy the code

Among them… ${expr} is used to define the [ES6 template string] ${expr} is used to embed expressions in the template character string.

4: a null value

JavaScript does not have the concept of a null value -(Void). In TypeScript, we use Void to represent functions that do not return any value:

function alertName() :void {
alert('My name is Tom');
}
Copy the code

Declaring a void variable doesn’t help much, because you can only assign it to undefined and null:

let unusable: void = undefined;
Copy the code

5: Null, and Undefined

In TypeScript, null and undefined are used to define these two primitive data types:

let u: undefined = undefined ;
let n: null = null;
Copy the code

Three: any value

An arbitrary value (Any) is used to indicate that assignments of Any type are allowed.

What is an arbitrary value type

If it is a common type, it is not allowed to change the type during assignment:

let myFavoriteNumber: string = 'seven';
myFavoriteNumber =7;
Error TS2322: Type 'number' is not assignable to Type 'string'.
Copy the code

However, if it is of any type, it is allowed to be assigned to any type.

let myFavoriteNumber: any = 'seven';
myFavoriteNumber = 7;
Copy the code

Properties and methods of arbitrary values

It is allowed to access any property on any value:

let anyThing:any ='hello';
console. log( anyThing.myName);
console. log(anyThing.myName.firstName);
Copy the code

It also allows any method to be called:

let anyThing: any = 'Tom' ;
anyThing. setName( 'Jerry');
anyThing. setName( 'Jerry' ). sayHello();
anyThing. myName. setFirstName('Cat');
Copy the code

You can say that after declaring a variable as an arbitrary value, any operation on it returns the type of the content that is an arbitrary value.

A variable of undeclared type

A variable is recognized as any value type if its type is not specified when it is declared:

let something; 
something = 'seven';
something = 7;
something . setName('Tom'); 
Copy the code

Is equivalent to

let something: any;
something = 'seven':
something = 7;
something. setName('Tom');
Copy the code

Four: type inference

If there is no explicit Type specified, TypeScript will infer a Type according to the rules of Type Inference.

What is type inference

The following code does not specify a type, but will report an error at compile time:

let myFavoriteNumber = 'seven'; 
myFavoriteNumber = 7;
Error TS2322: Type 'number' is not assignable to Type 'string'.
Copy the code

In fact, it is equivalent to:

let myFavoriteNumber: string = 'seven' ; 
myFavoriteNumber = 7;
Error TS2322: Type "number' is not assignable to Type 'string'.
Copy the code

TypeScript extrapolates a type when no type is explicitly specified. This is called type inference. If no assignment is made, it is inferred to be of type any and is not checked at all:

Five: joint type

Union Types indicate that the value can be one of many Types. Use or link |

Simple example

let myFavoriteNumber: string | number ;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
let myFavoriteNumber: string I number;
myFavoriteNumber = true;
// index.ts(2,1): error TS2322: Type ' boolean' is not assignable to type'stringI number'.
//Type 'boolean' is not assignable to type 'number '.
Copy the code

Associative type use|Separate each type.

Here let myFavoriteNumber: string | number means, allow myFavoriteNumber is of type string or number, but not other types.

Access a property or method of the union type

When TypeScript doesn’t know what type a variable of a union type is, we can only access properties or methods that are common to all types of the union type:

function getLength (something: string | number) :number {
returnsomething.Length; }/ / index. Ts (2, 2) : error TS2339: Property 'length' does not exist on the type string | number '.
// Property 'length' does not exist on type 'number'. 

Copy the code

In this example, length is not a common attribute of string and number, so an error is reported. There is no problem accessing the common attributes of string and number:

function getSt ring( something: stringI number) :string {returnsomething. toString(); }Copy the code

Six: The type of the object – interface

In TypeScript, we use Interfaces to define the types of objects.

What is an interface

In object-oriented languages, Interfaces are an important concept. They are an abstraction of behavior, and it is classes that implement implement.

Interfaces in TypeScript are a very flexible concept. In addition to abstracting some of the behavior of a class, interfaces are often used to describe the Shape of an object

Simple example

interface Person {
name: string;
age: number;
// Let must have the same format as above
let tom: Person = {
name: 'Tom' ,
age: 25
};
Copy the code

In the example above, we define an interface Person, followed by a variable Tom, whose type is Person. Thus, we are constrained that the shape of Tom must be the same as the interface Person.

The interface is partially capitalized. Some programming languages recommend that the interface name be prefixed with I

It is not allowed to define a variable with fewer attributes than the interface:

interface Person {
name: string;
age: number;
// Let must have the same format as above
let tom: Person = {
name: 'Tom' ,
//age: 25


interface Person {
name: string;
age: number;
// Let must have the same format as above
let tom: Person = {
name: 'Tom' ,
age: 25.color:blue/ / an error. More won't do
Copy the code

As you can see, when assigning a value, the shape of the variable must match the shape of the interface.

Optional attribute

Sometimes we don’t want to match a shape exactly, so we can use the optional property:?

interfacePerson name: string; age? : number; let tom: Person = {name: 'Tom '
};
interface Person {
name: string; age? :number;
};
let tom: Person = {
name: 'Tom'
age: 25
};
Copy the code

The implication of an optional attribute is that it may not exist. Undefined attributes are still not allowed:

interface Person {
name: string; age? :number;
}
Let tom: Person = {
name: 'Tom'.age: 25.gender: 'male '
}
Examples /p layground/ index.ts(9,5): error TS2322: Type '{name: string; age: number; gender: string; }' is not assignable to type ' Person 'Object literal may only specify known properties, and ' gender' does not exist in type 'Person'.
Copy the code

Any attribute

Sometimes we want an interface to allow arbitrary attributes. This can be done as follows:

interface Person {
name: string; age? :number;
[propName: string] :any;
}
let tom: Person = E
name: 'Tom' ,
Q
gender:,'male'
};
Copy the code

Use [propName: string] to define any attribute that takes a string value. Note that once an arbitrary attribute is defined, the type of both the deterministic attribute and the optional attribute must be a subset of its type: arbitrary [propName: string]: string;

interface Person {
name: string; age? :number;
// For any type, we usually write any
[propName: string] :any;
}
let tom: Person = {
name: 'Tom' ,
age: 25 ,
gender:'male'
};
Copy the code

Read-only property

Sometimes we want fields in an object to be assigned only at creation time, so we can use readonly to define read-only properties:

interface Person {
readonly id: number ;
name: string; age? :number ; 
[propName: string] :any;
}
// readonly attributes are declared with readonly. The value is given when the variable is declared.
let tom: Person = {
id: 89757.name: ' Tom' ,
gender: ' male '
};
tom.id = 9527;
Ts (14,5): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
Copy the code

In the above example, the attribute ID defined by readonly was initialized and then assigned again, so an error was reported. Note that the read-only constraint exists the first time an object is assigned, not the first time a read-only property is assigned:

interface Person { readonly id: number ; name: string; age? : number ; [propName: string]: any; }// readonly attributes are declared with readonly. The value is given when the variable is declared.
let tom: Person = {
name: ' Tom' ,
gender: ' male '
};
tom.id = 9527;
Copy the code

In the preceding example, two error messages are reported:

1: did not assign id when assigning Tom.

2: An error was reported when assigning tom.id because it is a read-only attribute.

Note that the read-only constraint exists the first time an object is assigned, not the first time a read-only property is assigned;

Practical application:

interface Config {
    type: string;
    url: string;
    data ? : string;
    dataType: string;
}

function ajax(config:Config) {
    var xhr = new XMLHttpRequet();
    xhr.open(config.type, config.url, true);
    xhr.send(config.data);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            console.Log('success')
        }
    }
}
ajax({
    type: 'get'.url: 'https:/ /www. baidu.com'.dataType: 'json'
})

Copy the code

Seven: Array type

Type + square brackets notation

The simplest way is to use “type + square brackets” to represent arrays:

let fibonacci: number[] = [1.1.2.3.5];
Copy the code

No other types are allowed in an array item:

let fibonacci: number[] = [1.'1'.2.3.5];
// Type 'string' is not assignable to type 'number'. 
Copy the code

The parameters of some array methods are also limited by the types agreed upon when the array is defined:

let fibonacci: number[] = [1, 1, 2, 3, 5]; fibonacci. push('8'); // Argument of type ""1" "is not assignable to parameter of type" number'Copy the code

In the example above, the push method is only allowed to pass an argument of type number, but it passes an argument of type 8. Here “8” is a string literal type, described in more detail in a later section.

An array of generics

We can also use Array Generic, Array

to represent arrays:

let fibonacci: Array<number> = [1.1.2.3.5];
Copy the code

Represent arrays with interfaces

Interfaces can also be used to describe arrays:

inter face NumberArray {
[index: number] :number;
let fibonacci: NumberArray = [1.1.2.3.5];
Copy the code

NumberArray indicates that the value type must be numeric if the index type is numeric.

Interfaces can also be used to describe arrays, but we generally don’t do this because it’s much more complicated than the first two approaches. One exception is that it is often used to represent an array of classes.

An array of class

The array-like object class has no Array methods and has the length attribute. Instead of an array type, as in arguments:

function sum() C
let args: number[] = arguments;
// Type 'IArguments' is missing the following properties from type 'number[]': pop, push, concat, join, and 24 more.
Copy the code

In the above example, arguments is actually an array of classes and should not be represented as a normal array; instead, arguments should be represented as an interface:

function sum() {
let args: {
[index: number] :number;
length: number;
callee: Function;
} = arguments;
}
Copy the code

In this example, in addition to restricting the type of the value to be a number when the index is of type number, we also restrict the length and callee attributes.

In fact, common class arrays have their own interface definitions, such as IArgyments, NodeList,HTMLCollection, etc. :

function sum() 
let args: IArguments = arguments;
}
Copy the code

IArguments are TypeScript defined types, which are essentially:

interface IArguments {
[index: number]: any;
Length: number;
callee: Function ;
}
Copy the code

Any is applied to the array

A common practice is to use any to indicate that any type is allowed in an array:

let list:any[] = ['sb'.25{website:'http://sb.com'}]
Copy the code

Eight: function type

Functions are first-class citizens in JavaScript

Function declaration

In JavaScript, there are two common ways to define functions: Function Dec La ration and Function Expression.

// Function Declaration
function sum(x, y) {
return x + y:
// Function Expression
let mySum = function (x, y) {
return x + y;
};
Copy the code

A function has input and output. To constrain it in TypeScript, both input and output are taken into account, where the type definition of a function declaration is simpler:

function sum(x: number, y: number) :number {
return x + y;
}
Copy the code

Note that entering extra (or less than required) parameters is not allowed


function sum(x: number, y: number) :number {
return x + y;
}
sum(1.2.3);

Ts (4,1): error TS2346: Supplied parameters do not match anysignature of call target.

function sum(x: number, y: number) :number {
return x + y:
} 
sum(1);
Ts (4,1): error TS2346: Supplied parameters do not match any signature of call target
Copy the code

Functional expression

If we were to write a definition of Function Expression now, it would look something like this:

Let: mySum = function (X:,numberY:,number) :,number.{
return X:+ y:
};
Copy the code

This can be compiled, but in fact the above code only types the anonymous function to the right of the equals sign, while the mySum to the left of the equals sign is inferred by type inference from the assignment operation. If we need to manually add the type to mySum, it would look like this:

let mySum: (x: number, y: number) = > number = function (x: number, y:number) :nunmber {
return X + y
};
Copy the code

Be careful not to confuse => in TypeScript with => in ES6. In TypeScript type definitions, => is used to represent function definitions, with input types enclosed in parentheses on the left and output types on the right.

In ES6, arrow functions are called arrow functions and are widely used. Refer to arrow functions in ES6

Define the shape of a function with an interface

We can also use an interface to define the shape of a function:

interface SearchFunc {
(source: string.subString: string): booLean;
let mySearch: SearchFunc;
mySearch = funct ion(source: string ,
subString: string) { 
returnsource.search( subString) ! = = -1;
}
Copy the code

Adopt the way of function expression | interface definition function, types of equal sign on the left side of the limit, can ensure that after the function name assignment guarantee number of parameters, parameter type, the return value type is constant.

Optional parameters

As mentioned earlier, entering extra (or less than required) parameters is not allowed. So how do you define the optional parameters? Similar to optional attributes in interfaces, we use? Represents optional parameters:

function bui LdName(f irstName: string, lastName? :string) {
if (lastName) {
return firstName + ' ' + lastName ;
} else {
return firstName ;
}
}
Let tomcat = buildName('Tom'.'Cat');
let tom = buildName( 'Tom' );
Copy the code

Note that optional parameters must be followed by required parameters. In other words, optional arguments are no longer allowed to be followed by required arguments:

function buildName (firstName? : string, lastName: string) { if (firstName) { return firstName + ' ' + las tName; } else { return Las tName ; } } let tomcat = buildName('Tom', 'Cat'); Let tom= buildName(undefined, 'Tom' ); // index.ts (1,40): error TS1016: A required parameter cannot follow an optional parameterCopy the code

Parameter Default Value

In ES6, we allow default values to be added to function arguments, and TypeScript recognizes arguments with default values as optional:

function bui LdName( firstName: string, lastName: string = 'Cat') {
return firstName + ' ' + lastName; 
let tomcat = buildName('Tom' , 'Cat');
let tom = buildName( 'Tom');
Copy the code

There is no constraint that optional parameters must be followed by required parameters:

function bui LdName (firstName: string = 'Tom', lastName: string) {
return firstName + ' ' + lastName; 
}
let tomcat = buildName('Tom', 'Cat');
let cat = buildName (undefined, 'Cat' );
Copy the code

For default parameters, refer to the default values of function parameters in ES6

The remaining parameters

In ES6, you can use… Get the rest of the function arguments (rest arguments) :

function push(array, ... items) {
items. forEach( function(item) {
ar ray . push( item) ;
});
}
Let a: any[] = [];
push(a, 1.2.3);
Copy the code

Items are, in fact, an array. So we can define an array by its type:

function push(array: any[], ...items: any[]) {
items . forEach( function(item) {
array. push( item);
});
}
leta=[];
push(a, 1.2.3);
Copy the code

Note that the REST parameter can only be the last parameter. For rest parameters, refer to REST parameters in ES6

overloading

Overloading allows a function to take different numbers or types of arguments and behave differently.

For example, we need to implement a function reverse that prints the number 321 when 123 is typed, and olleh when hello is typed.

With union types, we can do this:

function reverse(x: number | string) :number | string {
    if (typeof x === 'number') {
        return Number(x.toString().split(' ').reverse().join(' '));
    } else if (typeof x === 'string') {
        return x.split(' ').reverse().join(' '); }}Copy the code

However, this has the disadvantage of not being able to express it exactly. When the input is a number, the output should also be a number, and when the input is a string, the output should also be a string. In this case, we can use overloading to define multiple reverse function types:

function reverse(x: number): number; function reverse(x: string): string; function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); }}Copy the code

In the example above, we defined the function reverse multiple times, the first several times as a function definition, and the last time as a function implementation. In the editor’s code prompt, you can see the first two prompts correctly.

Note that TypeScript matches function definitions first, so multiple function definitions that have inclusion relationships need to have the exact definition first.

Let’s say we need to write a function that only three people can follow: Yao Ming, Kobe Bryant and lebron James. Only when the name is yao Ming, he can play center, is when kobe Bryant can play guard, is time to play forward, James and because domestic players are more thin, so only when yao Ming is more than 25 years old, can be classified as qualified center (just for example, don’t take it too seriously), then this time use specific overloading the signature.

function playBasketball(name: 'YaoMing', age: number) :void;

function pLayBasketbalL(name: 'Kobe ', age ? : number) :void

function playBasketball(name: 'James', age ? : number) :void;

function playBasketball(name: string, age ? : number) {
    if (name ===
        'YaoMing' && age && age >= 25) {
        console.log('good Center')}else if (name === 'Kobe') {
        console.Log('good guard')}else if (name === 'Jams') {
        console.Log('good forward')}else {
        console.log('ordinary baskerball player')
    }
}
playBasketball('YaoMing'.25);
playBasketball('Kobe');
Copy the code

Ix: the enumeration

The enumeration (Enum) type applies to scenarios where the value is limited within a certain range, for example, there are only seven days in a week, and the color is limited to red, green and blue.

Simple example

Enumeration is defined using the enum keyword:

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
Copy the code

Enumerators are assigned incrementing numbers starting from 0 and 0, and the enumerator values are also reversely mapped to the enumerator names:

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
console. log(Days["Sun"] === 0); // true
console. Log(Days["Mon"] === 1); // true
console. Log(Days["Tue"] === 2); // true
console. log(Days["Sat"] === 6); // true
console. Log(Days[0] === "Sun"); // true
console. log(Days[1] === "Mon"); // true
console. log(Days[2] === "Tue"); // true
console. log(Days[6] === "Sat"); // true
Copy the code

Manual assignment

We can also assign enumerations manually:

enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};

console. log(Days["Sun"= = =7); // true
console. log(Days ["Mon"= = =1); // true 
console. log(Days["Tue"= = =2); // true
console. Log(Days["Sat"= = =6); // true 
Copy the code

In the above example, enumerators that are not manually assigned are incremented after the previous enumerator.

TypeScript doesn’t notice if an unmanually assigned enumeration item duplicates the manually assigned one:

enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
console. log (Days["Sun"= = =3); // true
console. Log(Days ["Wed"= = =3); // true
console. log(Days[3= = ="Sun"); // false
console. Log(Days[3= = ="Wed"); // true 
Copy the code

Use of classes in TypeScript

Public private and protected

TypeScript uses three types of Access Modifiers, public,private, and protected.

Properties or methods decorated by public are public and can be accessed anywhere. By default, all properties and methods are public

A private modifier property or method is private and cannot be accessed outside the class in which it is declared. A modifier property or method is protected, just like private, except that it is accessible in subclasses. Here are some examples:

class Animal {
    public name;
    public constructor(name) {
        this.name = name; }}let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom
Copy the code

In the above example, name is set to public, so direct access to the instance’s name attribute is allowed. Most of the time, we want attributes that are not directly accessible, so we can use private instead:

class Animal { private name; public constructor(name) { this.name = name; } } let a = new Animal('Jack'); console.log(a.name); a.name = 'Tom'; // index. ts(9,13): error TS2341: Property 'name' is private and only accessible within class "Animal' // index.ts (10,1): error TS2341: Property 'name' is private and only accessible within class ' Animal'Copy the code

Note that TypeScript compiled code does nothing to limit the external accessibility of private properties. – The above example compiles the following code:


var Animal = (function () {
    function Animal(name) {
        this.name = name;
    }
    returnAnimal; }) ();var a = new Animal('Jack');
console.log(a.name);
a.name = 'Tom';
Copy the code

Attributes or methods that use private modifiers are also not accessible in subclasses:

class Animal {
    private name;
    public constructor(name) {
        this.name = name; }}class Cat extends Animal {
    constructor(name) {
        super(name);
        console.log(this.name); }}// index.ts (11,17): error TS2341: Property 'name' is private and only accessible within class 'Animal'
Copy the code

If protected., access is allowed in subclasses:

class Animal {
    protected name;
    public constructor(name) {
        this.name = name; }}class Cat extends Animal {
    constructor(name){
    super(name);
    console.log(this.name); }}Copy the code

When the constructor is modified to ‘private’, the class is not allowed to be inherited or instantiated:


class Animal {
    public name: any;
    nane: string;
    private constructor(name: string) {
        this.nane = name; }}class Cat extends Animal {
    constructor(name: string) {
        super(name); }}let a = new Animal('Jack');
    Ts (7,19): TS2675: Cannot extend a class 'Animal'. Class constructor is marked as private.
    Ts (13,9): TS2673: Constructor of class 'Animal' is private and only accessible within the class dec laration.
Copy the code

When the constructor is protected, the class is only allowed to be inherited:

class Animal {
    public name;
    protected constructor(name) {
        this.name = name; }}class Cat extends Animal {
    constructor(name) {
        super(name); }}let a = new Animal('Jack');
/ / index. Ts (13, 9) : TS2674: Constructor of class ' Animal' is protected and only accessible within the class dec laration.
Copy the code

Parameter properties

Modifiers and readonly can also be used in constructor arguments to assign a value to the property as defined in the class, making code more concise.

class Animal{
// public name: string;
public constructor(public name) {
    // this.name = name;}}Copy the code

readonly

A read-only property keyword that is allowed only in a property declaration or index signature or constructor.

class Animal {
readonly name;
public const ructor(name) {
this.name = name ;
}
let a = new Animal('Jack' );
console. Log(a.name); // Jack
a.name = 'Tom';
// index.ts(10,3): TS2540: Cannot assign to 'name' because it is a read-only property 
Copy the code

Note that if readOnly and other access modifiers exist at the same time, they need to be written after them.

class Animal {
    // public readonly name;
    public constructor(public readonly name) {
        // this.name = name ;}}Copy the code

An abstract class

Abstract is used to define abstract classes and their abstract methods. What is abstract class? First, abstract classes are not allowed to be instantiated:

abstract class Animal {
    public name;
    public constructor(name: string) {
        this.name = name;
    }
    public abstract sayHi();
}
let a = new Animal('Jack');

Ts (9,11): error TS2511: Cannot create an instance of the abstract class 'AnimaL'.
Copy the code

In the example above, we define an abstract class Animal and an abstract method sayHi. An error occurred while instantiating an abstract class.

Second, abstract methods in abstract classes must be implemented by subclasses:

abstract class Animal {
    public name;
    public constructor(name: string) {
        this.name = name;
    }
    public abstract sayHi();
}
class Cat extends Animal {   
    public eat() {
        console.log(`The ${this.name } is eating.`); }}let cat = new Cat('Tom');
/ / index. Ts (9, 7) : error TS2515: Non-abstract class 'Cat' does not IMP Lement 'sayHi' from class' Anima L'.
Copy the code

In the example above, we defined a Cat class that inherited from the abstract Animal class, but did not implement the abstract sayHi method, so the compilation failed.

Here is an example of using abstract classes correctly:


abstract class Animal {
    public name;
    public constructor(name: any) {
        this.name = name;
    }
    public abstract sayHi();
}
class Cat extends Animal {
    public sayHi() {
        console.log(`Meow, My name is The ${this.name}`); }}let cat = new Cat('Tom');
Copy the code

It is too hard to write, please give a thumbs up, ball ball