Approaching ts, it’s cool to use, and it’s always cool after use (1)

Time:2021-3-2

preface

Vue3 has been released, the pace of TS has been unable to stop, only ES6? Don’t think about it, people are already in action, the following is the basic series of TS tutorial, TS basic grammar, advanced grammar, and how to apply ts in Vue project, follow me quickly roll up.

Basic data type

number
const a: number = 3;
character string
const b: string = "1";
array
const c: number[] = [1, 2, 3];
const d: Array<number> = [1, 3];
const arr: any[] = [1, "33", true];
tuple

You can define the corresponding type for each parameter in the array

const e: [number, string] = [1, "ww"];
enumeration
enum error {
  blue = 3,
  "orange",
}
const f: error = error.orange;
console.log (f) ; // output 4

tips

  1. Ifunassigned OnOne value is a numberSo this oneUnassigned valueThe value of the previous value is + 1
  2. Ifunassigned OfThe last value is not assignedSo the output is its outputsubscript
  3. IfThe value of the last unassigned value is non numeric, then it must be assigned
Boolean type
const g: boolean = true;
object

const i: object = {};
undefined

Commonly used in combination types

let j: number | undefined;
null
let k: null;
void

The specified method type indicates that there is no return value and cannot be used in the method bodyreturn

function aa(): void {
  console.log(1);
}

//If the method has a return value, you can add the type of the return value
function bb(): number {
  return 1;
}
never

Subtypes of other types, including null and undefined, represent values that never appear

let l: never;

//Anonymous function and throw an exception
l = (() => {
  throw new Error("111");
})();
Any type

Let parameters be of any type


let h: any = 1;
h = true;
h = "st";

function

Function declaration
function cc(): void {}
Methods to pass the reference
Function getUserInfo (Name: string, age?: number, School: String = Tsinghua University){
  return `name:${name}--age:${age}--school:${school}`;
}

Tips:? Indicates that this parameter can be passed or not. If it is not passed, it is undefined, or a default value can be defined

Residual parameters

When passing multiple parameters, if the remaining parameters are used, the undefined parameters can be converted to an array.

function sum (a: number, b: number, ...arr: number[]): number {
  let sum: number = a + b;
  arr.forEach((element) => {
    sum += element;
  });
  console.log(arr); [3,4,5]  
  return sum;
}
console.log(sum(1, 2, 3, 4, 5)); //15
function overloading
function reload(name: string): string;
function reload(age: number): string;
function reload(param: any): any {
  Return type of param = = = string "?'I am ${param} ':'My age: ${param}';
}
console.log (reload (18)); // age

tips: OverloadedWhat is the best way to do itThere is no method bodyAccording to the type of the parameter, you can choose one of the methods and judge the parameterThe parameter type passed in is not the parameter type of any overloaded methodIt’s not allowed to go through.

The first overload (of 2), "(Name: String): string", with the following error.
   Parameters of type 'never [] cannot be assigned to parameters of type' string '.
 The second overload (of 2), "(age: number): string", with the following error.
   Parameters of type 'never [] cannot be assigned to parameters of type' number '

class

class Person {
  //Private variables
  private name: string;
  
  //Constructors
  constructor(name: string) {
    this.name = name;
  }
  
  //Get the name
  getName(): string {
    return this.name;
  }
  
  //Set name
  setName(name: string): void  {
    this.name = name;
  }
}

Let P = new person ("Zhang San");
p. Setname ("Li Si");
console.log(p);

inherit

class Son extends Person {
 //Static properties
  public static age: number = 18;
  //School
  public school: string;
  //Construction method
  constructor(name: string, school: string) {
    //Before accessing "this" in the constructor of a derived class, you must call "super" to initialize the parent class constructor -- and pass the parameters to the parent class
    super(name); 
    //Assign the passed in school to the global variable
    this.school = school;
  }
  //Static method
  static run(name: string): string {
    Return '${name} is running, and his age is just${ this.age }`;
  }
}

Let son = new son ("Wang Wu", "Tsinghua University");
son.setName ("Zhao Liu"); // private classes cannot be accessed outside subclasses, but they can be assigned and accessed through public methods
console.log(son);
console.log ( Son.run (Fang Qi));
console.log(Son.age);

tips:

  1. Public can be accessed in the current class, subclass and outside the class
  2. Protected is accessible inside the current class and subclass, but not outside the class
  3. Private is accessible inside the current class, but not outside the subclass or class.
  4. Attributes are public by default without modifiers

polymorphic

Through abstract method / method overloading — implementing polymorphism — polymorphism is used to define standards

//Abstract parent class
abstract class Animal {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }
  //Abstract member -- Method
  abstract eat(): any;
  //Abstract members -- properties
  protected abstract ages: Number;
  sleep(): void {
    console.log ("sleep");
  }
}

class cat extends Animal {
  ages: Number = 2;
  constructor(name: string) {
    super(name);
  }
  //The non abstract class "cat" does not automatically implement the abstract member "eat" inherited from the "animal" class. It is necessary to manually define the abstract method polymorphism in the parent class
  eat(): string {
    Return "cats eat fish.";
  }

  //Polymorphism
  sleep(): string {
    Return "the cat is sleeping.";
  }
}

console.log(new cat("33").sleep());

tips:

  1. Abstract classes cannotinstantiation
  2. When a non abstract class inherits an abstract parent classNot automaticallyAbstract member from parent class, mustManual definitionThe abstract member in the parent class, otherwise an error is reported.
  3. Abstract members includeattributeandmethod

Interface

In object-oriented programming, interface is the definition of a specification, which defines the specification of behavior and action,

In programming, the interface plays a role of restriction and specification.

The interface defines the specifications that a batch of classes need to comply with. The interface does not care about the internal state data of these classes, nor the implementation details of the methods in these classes. It only stipulates that some methods must be provided in these classes, and the classes that provide these methods can meet the actual needs. The interface in TS is similar to Java, and more flexible interface types are added, including attribute, function, indexable and class.

Property interface
interface InterfaceName {
  first: string;
  Second?: string; // add a question mark, and the interface property can be transferred, but not transferred. The default is undefined.
}
//Print variables
function logParam(name: InterfaceName): void {
  console.log(name.first, name.second, 11);
}
//Defining parameters
const obj = { first: "1", second: "fff", three: 1 };
//Logparam ({first: "1", second: "1", three: 1}); // an error is reported. Only the value defined by the interface can be transferred
logParam(obj);

Tips: use variables to store incoming variables, so that values other than the defined interface can be passed in. Otherwise, if you directly pass in values without interface definition in the object, an error will be reported. Therefore, it is recommended that values defined by the interface be passed in.

Function type interface

The parameter type and return value type passed in by the method can be constrained in batch.

interface keyMap {
  (key: string, value: string): string;
}
let logKeyMap: keyMap = function (key1: string, value: string): string {
  return key1 + value;
};
console.log(logKeyMap("key1", "value"));

Tips: the interface only restricts the type and number of parameters passed in, not the parameter name.

Indexable interface
  • Constraint array
interface Arr {
  [index: number]: string;
}
let ss: Arr = ["2121"];
  • Constraint object
interface Obj {
  [index: string]: string;
}

let interfaceArr: Obj = { aa: "1" };

tips:

  1. yesarrayTo constrain,indexYou have to follow after thatnumberType.
  2. yesobjectTo constrain,indexYou have to follow after thatstringtype
  3. Index signature parameter type must be ‘string’ or ‘number’
Class type interface
  • yesclassConstraint, similar toabstract classThe implementation of the.
interface Animals {
  name: string;
  eat(): void;
}

class Dogs implements Animals {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  eat() {}
}
  • Interface inheritance — interfaces can inherit interfaces
interface Dog {
  eat(): void;
}

interface Persons extends Dog {
  work(): void;
}

class Cat {
  code() {
    console.log (the cat is tapping the code);
  }
}

//Implement interface after inheritable class
class SuperMan extends Cat implements Persons {
  eat(): void {
    console.log(1);
  }
  work(): void {
    console.log(2);
  }
}
let superMan = new SuperMan();
superMan.code();

Tips: the class interface will affect theattributeandmethodSimilar to non abstract classes, some methods and properties must be implemented when inheriting abstract classes, but the constraints on the types of properties and methods are more strict, except for methodsVoid typeCan beRedefiningIn addition, the type definitions of other properties or methods need to be consistent with the interface.

generic paradigm

In software engineering, we should not only create a consistent well-defined API, but also consider reusability.
Components can not only support current data types, but also support future data types, which provides you with very flexible functions when creating large-scale systems

Generics is the solutionclassInterfacemethodOfReusability, and yesNo specific data typeWe need your support.

Requirement: the parameters passed in are the same as those returned

Generics of functions
function getDate<T>(value: T): T {
  return value;
}
console.log(getDate<number>(123));

Tips: hereTIt can be changed to any other value, but the defined value is the same as the incoming parameter and the returned parameter. The general default writing method is t, which is also the choice of industry specifications.

Generics of classes
class MinClass<T> {
  public list: T[] = [];
  //Add
  add(value: T): void {
    this.list.push(value);
  }
  
  //Minimum value
  min(): T {
    //Let's say that's the minimum
    let minNum = this.list[0];
    for (let i = 0; i < this.list.length; i++) {
    //Compare and get the minimum value
    minNum = minNum < this.list[i] ? minNum : this.list[i];
    }
    return minNum;
  }
}
//Instantiate the class and specify that the type of T of the class is number
let minClass = new MinClass<number>(); 
minClass.add(23);
minClass.add(5);
minClass.add(2);
console.log(minClass.min());
 //Instantiate a class and specify that the type of T of the class is string, then the parameter passing and return of its method are all string types
let minClass2 = new MinClass<string>();
minClass2.add("23");
minClass2.add("5");
minClass2.add("2");
console.log(minClass2.min());
Generics of interfaces
  • The first way of writing
interface ConfigFn {
  //Specification parameter type, return value type
  <T>(value: T): T;
}

let getData: ConfigFn = function <T>(value: T): T {
  return value;
};

console.log(getData<string>("z11"));
  • The second way of writing
interface ConfigFn<T> {
  //Parameter type, return value type
  (value: T): T;
}

//Interface method
function getData<T>(value: T): T {
  return value;
}

//Using interfaces
let myGetDate: ConfigFn<string> = getData;
console.log(myGetDate("3"));

Tips: the generic interface is only for the interface of function type

Class as a parameter into the generic class
//User class -- mapping to database table fields
class User {
  username: string | undefined;
  password: string | undefined;
  //Constructor - initialization parameters
  constructor(param: {
    username: string | undefined;
    password?: string | undefined;
  }) {
    this.username = param.username;
    this.password = param.password;
  }
}


//Database class
class Db<T> {
  add(user: T): boolean {
    console.log(user);
    return true;
  }
  updated(user: T, id: number): boolean {
    console.log(user, id);
    return true;
  }
}

let u = new User({
  User name: "Zhang San",
});

//u. User name = Li Si;
u.password = "111111";
let db = new Db<User>();
db.add(u);
db.updated(u, 1);

Tips: the parameter name and type of the class are constrained.

modular

The internal module is called the namespace, and the external module is called the module for short. The module executes in its own scope, not in the global scope;

This means that variables, functions, classes, etc. defined in a module are not visible outside the module unless you explicitly use themexportOne of the forms derives them.

On the contrary, if you want to use the variables, functions, classes, interfaces, etc. exported by other modules, you have to import them. You can useimportOne of the forms.

We can separate some common functions into a file as a module.
The variables, functions and classes in the module are private by default. If we want to access the data (variables, functions and classes) in the module externally
We need to get throughexportExpose the data in the module (variables, functions, classes…).
After exposure, we passedimportBy introducing a module, you can use the data exposed in the module (variables, functions, classes…)

//modules/db.ts
function getDate(): any[] {
  console.log ("access data");
  return [
    {
      User name: "Zhang San",
    },

    {
      User name: "Li Si",
    },
  ];
}

//A module can be used many times
// export { getDate };
//A module can only be used once
export default getDate;
 import { getDate as getDbDate } from "./modules/db";
 import getDbDate from "./modules/db";
 getDbDate();

Tips: this can’t be used directly in the browser during debugging. You cannodeandweakpackDebugging in the environment.

Namespace

In the case of large amount of code, in order to avoid the conflict of variable naming, functions, classes and interfaces with similar functions can be placed in the namespace
Typescript’s namespace can wrap code and only expose objects that need to be accessed externally.

The difference between namespace and module

  • Namespace: internal module, mainly used to organize code and avoid naming conflicts.
  • Module: short for TS external module, focusing on code reuse, a module may have multiple namespace.
// modules/Animal.ts
export namespace A {
  interface Animal {
    name: String;
    eat(): void;
  }

  export class Dog implements Animal {
    name: String;
    constructor(theName: string) {
      this.name = theName;
    }
    eat() {
      console.log (I am)+ this.name );
    }
  }
}

export namespace B {
  interface Animal {
    name: String;
    eat(): void;
  }

  export class Dog implements Animal {
    name: String;
    constructor(theName: string) {
      this.name = theName;
    }
    eat() {}
  }
}
import { A, B } from "./modules/Animal";
 Let EE = new A. dog ("Xiaobei");
 ee.eat();

Ornament

  • Class decorator: class decorator is declared before class declaration (next to class declaration). Class decorator is applied to class constructor and can be used to monitor, modify or replace class definition.
function logClass(params: any) {
  console.log(params);
  //Params refers to the current class -- httpclient
  params.prototype.apiUrl  ="Dynamic extended attributes";
  params.prototype.run = function () {
    console.log (the "dynamic expansion method");
  };
  params.prototype.getDate = function () {
    console.log ("dynamic expansion method 2");
  };
}

@logClass
class HttpClient {
  constructor() {}
  getDate() {
    console.log(1);
  }
}

let http: any = new HttpClient();
console.log(http.apiUrl);
http.run();
http.getDate();

Tips: the decorator will override the methods in the decorated class.

  • Decoration factory

A decorator that can transmit parameters

function logClassB(param: string) {
  return function (target: any) {
    console.log (target, "class below decorator");
    console.log (param, "attribute passed in by decorator");
  };
}

@Logclassb ("Xiaohui")
class HttpClients {
  constructor() {}
  getDate() {}
}

let https: any = new HttpClients();
console.log(https);
  • Constructor decorator
function logClassC(target: any) {
  console.log(target, 1111);
  //Use here to inherit the target class and overload methods and properties
  return class extends target {
    a: Any = I am the modified attribute;
    getDate() {
      console.log (this. A + "-- output of method in decorator");
    }
  };
}

@logClassC
class HttpClient2 {
  public a: string | undefined;
  constructor() {
    This. A "I am a in the constructor";
  }
  getDate() {
    console.log(this.a);
  }
}
const https2 = new HttpClient2();
https2.getDate();
To be continued~

Next issue: use ts in Vue.