Ts, as a new technology, has become more and more popular in the past two years. After a period of learning and understanding, I wrote this article to guide you to easily master typescript by recording the core knowledge points of TS, hoping to impress you on the screen.

Typescript basic syntax

TypeScript supports almost the same data types as JavaScript, and it also provides useful enumerated types for us to use. Let’s take a quick look at the use of these types.

The base type

// Let isFlag: Boolean = true // Let myNumber:number = 24 // Let STR :string = 'ykk' // Array type, Let arr:number[] = [1,2,3] // if the array has different types let arr1: (number | string) [] = [1, '2', 3] / / an Array type, using an Array of generics (detailed analysis on generic later) let arr: Array < number > = (4 and 6) / / tuple type, Let yuan: [string, number]; let yuan: [string, number]; // initialize yuan yuan = ['yuan', 12]; Yuan = [12, 'yuan']; // Error // Enumeration type, which can give friendly names to a group of values enum ActionType {online, offline, Deleted} let action:ActionType = actiontype. offline // 1 // any, indicating any type, Let color:any = 1 color = 'red' // void; when a function returns no value, it usually sets the return type to void function getName(): void { console.log("This is my name"); } // let obj:object; // Let obj:object; obj = {num: Const t = {name:string, age:number} = {name:'ykk', Const getTt () => number = () => {return 123; const getTt () => number = () => {return 123; } function errobocketter (): never {throw new Error(); console.log(123) }Copy the code

Interface

interface Person {
    name: string;
    age: number;
    phone: number;
}

let man:Person = {
    name: 'ykk',
    age: 18,
    phone: 13711111111
}
Copy the code

The type checker does not check the order of attributes, as long as the corresponding attributes exist and the type is correct. Second, we can define optional and read-only properties. Optional attributes indicate that some attributes in the interface are not required and may or may not be defined. · Make certain attributes in the interface read but not assigned, as follows:

interface Person { name: string; age? : number; readonly phone: number; }Copy the code

In real scenarios, we often encounter uncertain attribute names and attribute value types. In this case, we can use index signatures to set additional attributes and types, as follows:

interface Person { name: string; [propName: string]: any; } // The name of the attribute must be string, and the value of the attribute can be of any type.Copy the code

Interfaces can also be inherited

Interface human extends Person {weight:55} interface human extends Person {weight:55}Copy the code

class

Like JS classes, typescript classes have public, private, and protected access types.

  • Public In TypeScript, members default to public, which allows them to be called outside of the class in which they are defined
  • Private means it can be used within a defined class, not outside of that class
  • Protected is similar to private, but protected can be used within classes and in inherited subclasses

Example:

class Person { public name:string = 'ykk'; private age:number = 18; protected weight:number = 55; constructor(){ } } class Man extends Person { public say(){ return this.weight } } let p = new Person() let m = new Man() console.log(p.name) //ykk console.log(p.age) // Error age is private property console.log(m.say()) //55Copy the code

Since getters and setters cannot be used directly in JS, we need to define the trigger with an Object.defineProperty. In TS it is much easier to declare it directly in class:

class Person { private _food: string = 'apple' get food() { return this._food } set food(name: String) {this._food = name}} let p = new Person() console.log(p.good) //apple p.good ="cookie" // reset food hereCopy the code

The static keyword in typescript attaches the method or property directly to the class, rather than to the newly generated instance. Design pattern in the classic singleton pattern, it is the most appropriate!

class Demo { private static instance: Demo; peivate contructor(public name:string){} static getInstance(){ if(! this.instance){ this.instance = new Demo('ykk') } return this.instance; } } const demo1 = Demo.getInstance(); const demo2 = Demo.getInstance(); console.log(demo1.name) console.log(demo2.name)Copy the code

Abstract classes are used as base classes for other derived classes. They are generally not instantiated directly. Unlike interfaces, abstract classes can contain implementation details of members. The abstract keyword is used to define abstract classes and to define abstract methods within an abstract class. Note that you cannot create an instance of an abstract class.

abstract class MyAbstract { constructor(public name: string) {} say(): void { console.log('say name: ' + this.name); } abstract sayBye(): void; Constructor () {super('ykk');} class SubMyAbstract extends MyAbstract {constructor() {super('ykk'); // In the constructor of a derived class you must call super()} sayBye(): void {console.log('bye'); } getOther(): void { console.log('loading... '); } } let department: MyAbstract; // Create a reference to an abstract type department = new SubMyAbstract(); // Allow instantiation and assignment of an abstract subclass department.say(); department.sayBye(); department = new MyAbstract(); // Error: cannot create an instance of abstract class department.getother (); // Error: method does not exist in declared abstract classCopy the code

Typescript advanced syntax

Federated type and type protection

The so-called joint type was introduced into the type of value can only be used to limit the | separating each type, so the number | string | Boolean said a value can be a number, a string, or Boolean. Such as:

interface person1 { name: string; age: number; } interface person2 { hby: string; age: number; } let man: person1 | person2Copy the code

If a value is a union type, then we can only access parts of it that are common (common attributes and methods). Since we can only access a common value, ts will tell us when we want to access one of them. In this case, we need type protection

Let man: person1 | person2; man = { name: 'ykk', age: 18, hby: } // Use as direct assertion to tell ts where to find if((me as person1).name) {console.log((me as person1).name); } if((me as person1).name) { console.log((me as person2).hby); } // Use in if(('name' in me)) {console.log(me.name); } if('hby' in me) { console.log(me.hby); } / / use the typeof function add (one: number | string, two: number | string) {if (typeof one = = "string" | | typeof two = = "string") {retrun ` ` ${one} ${two}} retrun one + two} / / using instanceof class a {num: 1} function b (obj: object | a) {if (obj instanceof a) {retrun  obj.num } }Copy the code

The generic

What is a generic type? What does it say in TS?

Function iSay<T>(arg: T): T {return arg; } let come = iSay<number>(123);Copy the code

Of course, generics can be used in many ways, so let’s explore them.

The function of generic
Function say<T>(arr:T[]){... }; Say < number > (,22,33 [11]); Function say<T, F>(name:T, age:F){... }; say<string, number>('ykk', 18);Copy the code
Class generics
class say<T>{
    constructor(name:T){
        ...
    }
}
var t = new say<string>("1")
Copy the code
Inheritance of generics
class say<T extends number|string>{ constructor(one:T){ ... }} var t = new say<string>("1") //Copy the code
Keyof is used in generics

Using keyof in generics means, as the name implies, iterating over an interface, each time the generic type is the keyof the current interface.

interface persons { name:string, age:number, get:boolean } var p = { name:'ykk', age:18, Function add<T extends keyof persons>(key:T):persons[T]{return p[key] add('name') console.log(p1) //ykkCopy the code

The namespace

When ts is used in the object-oriented way, if you declare multiple instances of class generation, you will find that there are several instances in the global, which will cause global pollution. Therefore, we need the keyword namespace to prevent global pollution.

namespace Main{ class circle { ... } class rect { ... } // If you want to export it for external use, you need to export export class SAN {... }} // There will be only one Main available globallyCopy the code

Declare global variables

Typescript often reports errors when using undeclared global functions or variables. The most common example is when we import js files, we often report the following error:

There are two solutions:

  • Execute as prompted relative tonpm install @types/xxxThe command.
  • You can add it at the corresponding locationxxx.d.tsTs will automatically retrieve the file and parse it, as follows:
Declare var superagent; declare var superagent; declare var superagent; .Copy the code

There are many more useful declarations that can be defined, but I’m not going to give you an example.

Write in the last

The core basis of TS is basically finished. Since it is a note-type article, there are many places worth discussing together. I hope you can put forward valuable opinions. Of course, there are many more advanced implementations of TS, including the use of vue and React. I will also learn fighting later.