typescript basic learning

Keywords: TypeScript

1: typescript introduction and environment construction

1. Introduction to typescript

TS is a superset of JavaScript and can be compiled into pure JavaScript. TS adds many features, such as data types, classes, inheritance and interfaces.

2. Build typescript environment

i. Project environment construction

Install node. JS = > Global typescript: npm i -g typescript

ii. Write a ts file and compile it

Write a. TS file = > command line TSC b.ts = > compile into a JavaScript file.

iii.vscode configuration automatic compilation

Execute instruction in current project

tsc --init

Generate a tsconfig.json file in the project root directory:

 

Automatically compile, select terminal > Run task > monitor typescript. After that, each time the file is saved, it will be compiled automatically.

2: Data type of typescript

The data types of typescript mainly include:

boolean type

Number type (number)

String type (string)

Array type (array)

tuple type

Enumeration type (enum)

Any type (any)

null and undefined

void type

never type

Format: let variable: type = variable value

1. boolean type

let flag:boolean=[false|true]

2. Number type

let num:number=12

let float:number=12.12

3. String type

let str:string='hello world'

4. Array type

let array:number[]=[1,2]
let str:string[]=['1','2']

Generic mode

let arr:Array<string>=['we','eo']

5. Tuple type

Tuple type is a kind of array type. You can specify the type of each element in the array

let tup:[string,number,boolean]=['we',21,false]

6. Enumeration type

definition:

enum Enumeration variable name{

      Enumeration class name=enum ,

      Enumeration class name 1=Enumeration value 1,

       .........

}

use

var   Variable: enumeration type = enumeration variable name. Enumeration name

or

var variable name = enumeration variable name. Enumeration name

 

enum flag{
   success=1,
   errorM=-1
}
var F:flag=flag.success
//var F=flag.success
console.log(F);

  When single enumeration items are of type number (number by default), if no value is assigned, the index value of the element will be printed. If the element in front of the element has a value, the value printed by the element will be changed to the previous element plus 1

  7. Any type (any)

When we get the dom node, we don't know what type to take, so we can use any type

let dom:any=document.getElementById('app')

 

8.null and undefined

i.undefined

The typescript must specify its variable type, otherwise it will report an error. At this time, when we only define no assignment, the variable will also report an error when using the variable

Undefined is provided to solve this problem. If the specified variable is of other types or undefined, no error will be reported if the value is not assigned.

ii.null

It is expressed as null, which is somewhat similar to undefined. A variable may be null or undefined

let num:number|undefined|null

iii.void type

Represents a method that defines no return value

function fn():void{
    console.log('q'); 
}

In contrast, you can specify the type of return value

function fn():number{
    return 1
}

 

9.never type

Never represents subtypes of other types (including null and underfined), represents values that have never appeared, and is an implicit type. Mainly reflected in

Never type can only be assigned by never type

let num:number;
num=12

When num type is declared as above, only one value of number type can be assigned to the variable during assignment. If not, an error will be reported

let nev:never
nev:(()=>{
throw new Error('error')
})()

The real writing method is as above, but it is not commonly used. It is generally solved by using any or multi type definitions.

let a:null|undefined|number|string|boolean

3, typescript function

1. Definition of typescript function

There is a return value

function name(params:type):type {
    return paramType
}
or
let name=function (params:type):type {
    return paramType
}

No return value

function name(params:type):void {
   
}
or
let name=function (params:type):void {
  
}

4, typescript classes and interfaces

Object: concrete, practical, representing a thing. The attributes and behaviors of an object are encapsulated to form a class.

 

1.typescript definition class

It uses a new feature of es6: the keyword class

class Person{
    
}

2. Properties in class

Class has three attributes: variable, constructor and method.

Variables can be divided into public variables, private variables and protection variables

class Person{
    public name:string;//If it is a public method, public can be omitted
    constructor(name:string){
        this.name=name
    }
    eat(){
        console.log('Common method'); 
    }
}

i. Instantiation class

var person=new Person('xiao Ming ')

Call:

person.eat()
person.name / / you can access directly by using the public modifier. If you use the private modifier, you can only provide public access methods get/set methods

ii.private keyword: static variable

Features: static variables cannot be called directly, but only by providing external access methods,

Benefits: it ensures the security of variables in the class and does not allow external direct access.

class Person{
    private name:string;
    constructor(name:string){
        this.name=name
    }
    eat(){
        console.log('Common method');
        
    }
    getName(){
        return this.name
    }
    setName(name:string){
        this.name=name
    }
}
var p =new person()

Directly through: p.name cannot access this variable, but can only be accessed and modified indirectly through getName/setName

p.getName()

p.setName("little red")

  3. Class inheritance: extends

Inheritance can only inherit the public attributes of the parent class, and private attributes cannot be inherited.

Inheritance can only be single inheritance, not multiple inheritance.

Class can only inherit single.

4. Class modifier

typescript provides three modifiers: public, protected, and private

The default is public, which can be omitted during definition.

protected: the modified attribute can only be used within the inheritance system.

private: defined properties can only be used in this class.

5. Static attribute and static method of class: keyword static

In es5, methods and properties are added directly through constructors, which are called static methods and static properties

function Person(){
   name:"xiaozhi"
   setName:()=>{
    console.log("Example method")
   }
}
Person.age="12"
Person.setAge=function(){
    console.log('Static method');
}
//Static call
Person.setAge()
Person.age
//Instance call
var p=new Person()
p.setName()
p.name

Static methods and static instances in typescript

Differences between static methods and properties and instance methods and properties

Static methods and instances can be called directly through the class name. Instance methods and properties need to be called using the instantiated class name.

Static methods and properties will not disappear after the class is called, but instance methods and properties will.

Define static properties and static methods

 class Person{
    static name2='xiaozhi';
    static  run(){
        console.log("go"); 
    }
}
Person.name2
Person.run()

6. Class polymorphism

Polymorphism: the same thing shows different states, indicating polymorphism. The parent class method value definition in polymorphism does not implement the function.

For example, water has three states: solid state, liquid state and gas state, so the parent is water, and the child is water in different states.

Then implement the following code

class water{
     name:string;
    constructor(name:string){
        this.name=name
    }
    waterState(){}
}
class Gutai extends water{
    constructor(name:string){
        super(name)
    }
    waterState(){
        console.log("I am"+this.name+"water"); 
    }
}
class Yetai extends water{
    constructor(name:string){
        super(name)
    }
    waterState(){
        console.log("I am"+this.name+"water"); 
    }
}
class Qitai extends water{
    constructor(name:string){
        super(name)
    }
    waterState(){
        console.log("I am"+this.name+"water"); 
    }
}
var gutai=new Gutai('solid state')
gutai.waterState()
var yetai=new Yetai('liquid state')
yetai.waterState()
var qitai=new Qitai('Gaseous')
qitai.waterState()

7. abstract class: abstract

An abstract class is the base class of a class

For example: everyone has to eat, sleep and breathe. If you extract the breath of eating, sleeping and breathing into a class and modify it with abstract, it will become an abstract class. The only thing is that the abstract class only provides behavior and does not execute behavior. What food you eat, how you sleep, how fast you breathe or how slow you breathe. The abstract class doesn't care. If you inherit me, these behaviors must be.

Abstract classes have the following features:

Abstract classes cannot be instantiated,

Members of abstract classes may not be abstract members, but classes with abstract members must be abstract classes.

Subclasses that inherit abstract classes must override the abstract methods of abstract classes.

A subclass can be an abstract class, indicating that the subclass must have this behavior.

To sum up: an abstract class is a class that provides behavior but does not perform behavior [people are an abstract class and have to eat. Xiaomi is a concrete class (or an abstract subclass, see below). No matter what you eat, you can eat whatever you want, but you must have the behavior of eating].

abstract class Person{
    abstract eat():any;
}
class Xiaoming extends Person{
     food:string;
     constructor(food:string){
         super()
         this.food=food
     }
      eat(){
          console.log("Xiao Ming can eat and is eating"+this.food);
          
      }
}
var xiaoming=new Xiaoming("Wo Wotou")
xiaoming.eat()

Members of abstract classes:

Member variable: it can be either a variable or a constant. When it cannot be modified with abstract (modification cannot initialize the variable)

Member method: it can be either a general method or an abstract method. The general method does not need to be rewritten (it is best to repair the variables that want to access the abstract class)

Constructor: Yes, it is used to initialize member variables.

abstract class Person{
     food:string;
    constructor(food:string){
        this.food=food
    }
    abstract eat():any;
    run(){
        console.log("Xiao Ming ate while running"+this.food);
        
    }
}
class Xiaoming extends Person{
     constructor(food:string){
         super(food)
     }
      eat(){
          console.log("Xiao Ming can eat and is eating"+this.food);  
      }
}
var xiaoming=new Xiaoming("Chinese Cabbage")
xiaoming.eat()
xiaoming.run()

5, interface: interface

In typescript, the interface is to restrict json data or expand classes. When restricting json data, it is mainly to restrict object data. The internal data format of standardized object data must be consistent with the interface.

1. Binding effect of interface

a. Interface extends json data (i.e. objects)

 

interface PersonIf{
    name:string;
    age:number;
    sex:boolean
}
function getPerson(obj:PersonIf):string{
    return ''
}
var obejct={
    name:'child',
    age:18,
    sex:false
}
getPerson(obejct)

  Interpretation: the getPerson function of the above code receives an object of type PersonIf, which is an interface that restricts the format of the transferred object parameters, that is, the obejct object must have the same properties as the interface and will report errors.

It is worth noting that the interface has some attributes, and the object must have them; Objects have attributes, and interfaces are not necessarily mandatory;

 

interface PersonIf{
    name:string;
    age:number;
    sex:boolean
}
function getPerson(obj:PersonIf):string{
    return return obj.name+obj.age
}
var obejct={
    name:'child',
    age:18,
}
getPerson(obejct)

In general, the json data that is transmitted by the back-end interface may be transmitted to the front end according to the different parameters of the request, and the data can be inconsistent with the field, or what direct parameters are missing. At this time, we can turn the constraint attribute of the interface into an optional value. Use "? Symbol

At this time, there are some attributes in the interface, which do not have to be in the object

interface PersonIf{
    name?:string;
    age?:number;
}
function getPerson(obj:PersonIf):any{
    return obj.name
}
var obj={
    name:'child',
}
 console.log(getPerson(obj));

It is worth noting that when optional parameters are used, there is a return value, and the return type defined by the method should be any, because it is unknown that the name is optional and may be an underfined.

Another way is: (you can see the constraints on the array, which are explained)

b. Interface constrains functions

The interface constrains the function, mainly the parameters and return values of the function

Format:

interface Interface name{
    (Parameter name 1:Parameter type 1,Parameter name 2:Parameter type 2,...):return type
}
interface PersonIf{
    (name:string,age:number):string
}
let fn:PersonIf=function(name:string,age:number):string{
    return name+age
}
console.log(fn('xiaozhi',18));

c. Interface constraints on arrays (or objects)

Format:

interface Interface name{
    [index:number]:Array element type
}

If it is an array, the type of index must be number. If it is an object, it can be string (it is not commonly used because the attributes of the object are different in many cases. You can use any to solve it)

Constraint array code:

interface array{
    [index:number]:string
}
let arr:array=['12','34']
console.log(arr);

Constraint object code:

interface obj{
    [index:string]:any
}
let duixiang:obj={
    name:'xiaozhi',
    sex:18,
    jop:{
        p1:'teacher',
        p2:'parent'
    }
}
console.log(duixiang.jop.p1,duixiang.name);

4. Extension of interface to class

It is a bit similar to abstract classes. If a class is compared to a person, it is extracted and encapsulated into an abstract class; What adds to people is the interface.

For example, Zhang San is a person, an abstract class that an individual will inherit (he is not a person if he doesn't eat, sleep or breathe); Zhang San pursues individuality, so he realizes the interface (only red eyebrows and green lipstick have personality). At this time, Wang Wu is also a person and needs the abstract class of successor. However, he does not pursue personality, so he does not implement this interface.

Class implementation interface can be understood like this!!!

interface PersonIf{
    name:string;
    age:number;
    kouhong():any;
}
class person implements PersonIf{
    name:string;
    age:number;
    constructor(name:string,age:number){
        this.name=name
        this.age=age
    }
    kouhong(){
        console.log(this.name+'this year'+this.age+'year,So put on lipstick');
    }
}
var p=new person("Zhang San",18)
console.log(p.kouhong());

  Note: Methods in the interface can only be defined and cannot have method bodies; Class implementation interface must override all properties and methods in the interface; Multiple interfaces can be implemented; Interfaces and interfaces can be inherited (generally, multiple implementations are enough, and inheritance is not necessary)

interface PersonIf1{
    id:string
    age:number;
    kouhong():any;
}
interface PersonIf2{
    name:string;
    meimao():any;
}
class person implements PersonIf1,PersonIf2{
    id:string;
    name:string;
    age:number;
    constructor(name:string,age:number,id:string){
        this.name=name
        this.age=age
        this.id=id
    }
    kouhong(){
        console.log(this.name+'this year'+this.age+'year,So put on lipstick');
    }
    meimao(){
        console.log("eyebrow"); 
    }
}
var p=new person("Zhang San",18,'11111')
console.log(p.kouhong());

  5. Notes

Class can inherit a class and implement multiple interfaces at the same time

6, Generics

Generics: generics provide a compile time type safety detection mechanism that allows programmers to detect illegal types at compile time The essence of generics is parameterized type, that is, the data type operated on is specified as a parameter.

1. Function generics

There is a requirement that a function can return any type, and any can be used. However, using any does not give up type checking. At this time, generics are needed to solve the problem, so that whatever type is passed in can be put back.

A generic type is a parameterized type that checks the validity of the parameter list.

function fn<T>(name:T):T{
    return name
}
//This call method is quite any
//Console.log (FN ('xiaozhi ');
//console.log( fn(12));
//console.log( fn(false));
console.log( fn<string>('Xiao Zhi'));
console.log( fn<number>(12));
console.log( fn<boolean>(false));

In the above code, < T > represents generic type, T represents generic type name (whatever is passed in), and the generic type here can also be a data type in typescript. In this code, the returned type is generic, and we can also specify the returned type (not generic)

function fn<Y>(name:Y):string{
    return 'CODD'
}
console.log( fn<string>('Xiao Zhi'));

  But the following code is wrong

function fn<Y>(name:Y):string{
    return name
}
console.log( fn<string>('Xiao Zhi'));

  Because the returned is name, and the type of name is not necessarily string, but may be number.

  2. Generic class

There is a requirement to define a class in which the function is to add array elements. It is required that only data of the same data type can be added.

class AddArray<T>{
     array:T[]=[];
    add(item:T):void{
        this.array.push(item)
    }
    getArray():any{
        return this.array
    }
}
var m=new AddArray<string>()
m.add('xiozhi')
m.add('xiaolei')
m.getArray()
console.log(m.getArray());
var m2=new AddArray<number>()
m2.add(12)
m2.add(13)
console.log(m2.getArray());

 

3. Generic interface

i. Function generic interface of generic interface

As the name suggests, it is to load generics on functions in the interface

interface DataInterface{
    <T>(str:T):T
}
var getData:DataInterface=function<T>(name:T):T{
    return name
}
console.log(getData("xiaozhi"));

ii. Generic interface

As the name suggests, you define generics on interfaces.

interface DataInterface<T>{
    (str:T):T
}
function fn<T>(name:T):T{
    return name
}
var getData:DataInterface<string>=fn
var getData1:DataInterface<number>=fn
console.log(getData("Xiaobai"));
console.log(getData1(12));

The generic type is directly specified at the time of definition to simplify the writing method (the function is called only once)

interface DataInterface<T>{
    (str:T):T
}
var getData:DataInterface<string>=function<T>(name:T):T{
    return name
}
console.log(getData("Xiaobai"));

7, typescript modularization

The JavaScript modularization method is used, the module content is exposed by export, and the exposed data is introduced by import.

Create the following file

Write to each file:

user.ts

import userImp from './userImp'
class User implements userImp{
    name:string
    age:number
    constructor(name:string,age:number){
        this.name=name
        this.age=age
    }
    getName():string|undefined{
        return this.name
    }
    setName(name:string):void{
        this.name=this.name
    }
    getAge():number|undefined{
        return this.age
    }
    setAge(age:number){
        this.age=age
    }
}
export default  User

userImp.ts

interface userImp{
    name:string
    age:number
}
export default userImp

 index.ts

import User from './user'
var user= new User('XIAOHZI',18)
console.log(user.age);
console.log(user.name);

  Because modular programming is compiled into JS and cannot be run by the browser, you need to run jindex.js file through node

  1. Namespace

When writing typescript, when there are many classes or variables defined, it may lead to naming conflicts. At this time, we can use namespaces to separate the code and avoid naming conflicts.

namespace space name {........}

In the namespace, you need to export the content to be exported through export.

namespace A{
   export class a{
        name:string|undefined
        getName():any{
            console.log(this.name);
            return this.name
        }
    }
}
namespace B{
 export  class a{
        name:string|undefined
        getName():any{
            console.log(this.name);
            return this.name
        }
    }
}
var Aa=new A.a()
var Ba=new B.a

If you want to modularize the namespace, you also need to use export to export the space

export namespace A{
   export class a{
        name:string|undefined
        getName():any{
            console.log(this.name);
            return this.name
        }
    }
}

8, Decorator

Decorator is a method that can inject content into a class, method, attribute and parameter to expand its function.

Mode of use

@Decorator name (param:any) {...}

Receive a parameter that represents the current class, method, property or parameter.

Main: to support decorators, you need to open them in the ts configuration file:

"experimentalDecorators": true,

1. No reference decorator

The parameterless decorator params is the class itself

function logDom(params:any){
    //param represents the class itself
    // Adds a property to the current class
   params.protoType.age='12'
    // Add method to class
    params.protoType.getAge=function(){
        console.log("11");   
    }
}
@logDom
class Dome{
    constructor(){}
    show():void{
        console.log("Tired");
    }
}
var dome:any=new Dome()
console.log(dome.age);
dome.getAge()

2. Parametric decorator: returns a function

params of the parameter decorator represents the passed in parameters, and target represents the class itself.

function logDom(params:any){
    //param represents the class itself
    // Adds a property to the current class
    console.log(params)
    return function(target:any){
        target.protoType.age='12'
        // Add method to class
        target.protoType.getAge=function(){
            console.log("11");
            
        }
    }
  
}
@logDom("Hello")
class Dome{
    constructor(){}
    show():void{
        console.log("Tired");
    }
}
var dome:any=new Dome()
console.log(dome.age);
dome.getAge()

Class decorators can also modify constructors and methods by overloading

function decorateDome(target:any){
    return class extends target{
        url:any='Hello'
        getUrl(){
            console.log("It is bad");
        }
    }
}
@decorateDome
class Dome{
    url:string|undefined;
    constructor(){
        this.url="I am a url"
    }
    getUrl(){
        console.log(this.url);
        
    }
}
var dome=new Dome()
console.log(dome.url,);
dome.getUrl()

3. Attribute decorator

One more function returned by the property decorator represents the property

function decorateDome(params:any){
    return function(target:any,atrr:any){
        target[atrr]=params
    }
    
}
class Dome{
    @decorateDome("Attribute decorator")
    url:string|undefined;
    constructor(){
        // this.url = "I am a url"
    }
    getUrl(){
        console.log(this.url);
        
    }
}
var dome=new Dome()
console.log(dome.url);

4. Method decorator

The function of the method decorator can be used to monitor, modify or replace the definition of the method

Three parameters need to be passed in when the method decorator runs

For static members, it is the constructor of the class, and for instance members, it is the prototype of the class

Member's name

Member's attribute descriptor

function decorateDome(params:any){
    return function(target:any,methodName:any,desc:any){
      console.log(params);
      console.log(target);
      console.log(methodName);
      console.log(desc);      
    }   
}
class Dome{
    url:string|undefined;
    constructor(){
        // this.url = "I am a url"
    }
    @decorateDome("Attribute decorator")
    getUrl(){
        console.log(this.url);
        
    }
}
var dome=new Dome()

  You can see that target is the class itself, methodName is the method name, desc is the expression of the method, and value is the method itself

a. Replace method with decorator

function decorateDome(params:any){
    return function(target:any,methodName:any,desc:any){
          desc.value=function(...args:any[]){
            console.log(args);    
          }
    }   
}
class Dome{
    url:string|undefined;
    constructor(){
    }
    @decorateDome("Attribute decorator")
    getUrl(){
        console.log(this.url);   
    }
}
var dome=new Dome()
dome.getUrl("Hello","haha")

 

At this time, we can see that the method has been replaced, but in many cases, we need to modify the method rather than replace it. At this time, we can use apply to modify the function

function decorateDome(params:any){
    return function(target:any,methodName:any,desc:any){
          var cMethod=desc.value
          desc.value=function(...args:any[]){
            console.log(args);  
            cMethod.apply(target,args)
          }
    }   
}
class Dome{
    url:string|undefined;
    constructor(){
        // this.url = "I am a url"
    }
    @decorateDome("Attribute decorator")
    getUrl(){
        console.log("I feel OK");  
    }
}
//var dome=new Dome()
var dome:any=new Dome()
dome.getUrl("Hello","haha")

  5. Method parameter decorator

Function: when the function is called, use the method decorator to add some properties or methods to the class prototype.

Format:

 return function(target:any,methodName:any,paramsIndex:any){
      ...  
    }

  paramsIndex: indicates the index of the parameter

function decorateDome(params:any){
    return function(target:any,methodName:any,paramsIndex:any){
      console.log(paramsIndex); 
      target.apiUrl="Ha ha ha"    
    }   
}
class Dome{
    url:string|undefined;
    constructor(){
        // this.url = "I am a url"
    } 
    getUrl(@decorateDome("hello") name:any){
    }
}
var dome:any=new Dome()
dome.getUrl("Hello")
console.log(dome.apiUrl);

  6. Execution sequence of decorator

Attribute decorator > method decorator > method parameter decorator > class decorator

If there are multiple decorators of the same kind, the execution sequence is from bottom to top, right to left.

 

Posted by SimpleManWeb on Sat, 06 Nov 2021 13:03:08 -0700