Record and learn the basic use of TS for follow-up troubleshooting and as a reference manual. It is boring to just read the document, so record the simple points of use.

The installation

npm install -g typescript
yarn global add typescrpt

mkdir tsproject && cd tsproject && touch index.ts >> echo "console.log(1)"

// Compile this file manually
tsc index.ts

// Initialize the ts project configuration file
tsc --init

/ / modify tsconfig. Json
 "outDir": "./src".// or vscode Terminal > Run Task > ts > tsconfig.json
tsc -w 
Copy the code

The core functionality of TS is in two words: type constraints.

The core function

The data type

Primitive data types include Boolean, numeric, string, NULL, undefined, and the new type Symbol in ES6 and BigInt in ES10.

/ / a Boolean
var flag: Boolean = true;

// number
var num1: Number = 100;
var num2: Number = 12.3;

// string
var str1: String = "anikin";

let myFavoriteNumber = 'seven';
myFavoriteNumber = 7;  Let myFavoriteNumber: string = 'seven'; let myFavoriteNumber: string = 'seven';

// array
var arr1: number[] = [1.2.3.4];
var arr2: Array<number> = [1.2.3.4]; / / generics
var arr3: [string.number] = ["anikin".100]; // Tuple type

// enum Enum type: enumerates the values of variables one by one. The values of variables are limited to these ranges
enum Flag {
  default.// The default value is index or the previous value +1 0
  success = 1,
  error = -1,
  last, / / 0
}
var f1: Flag = Flag.success;
// console.log(Flag.default, Flag.last);

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
// Days['Sun'] = 0;

/ / any use
var box:any = document.getElementById("app");
box.style.color = "red";

// undefined || null
var usrinfo: undefined;
var num3: number | undefined;
num3 = 100;
Copy the code

function

// Function Declaration
function show() :void {} // No return value
function conso(name: String, age: number) :string {
  return `${name}= = =${age}`;
}

// Function Expression
const myAdd2 = (x: number, y: number) = > x + y;

/ / anonymous
var getInfo = function () :void {};

// Optional parameter Age is optional
// Optional must be placed at the end
// The name is the default parameter. The default parameter is optional. If it is not the last bit, you need to pass a parameter
function conso2(name: String = "zhangsan", age? :number) :string {
  return `${name}= = =${age}`;
}


// Implement the function summation... Rest :number[] Specifies the expanded array
// The rest of the argument is init = 1
function add(initValue: number. rest:number[]) :number {
  var res = initValue;
  for (let index = 0; index < rest.length; index++) {
    res += rest[index];
  }
  return res;
}
/ / add (1, 2, 3, 4, 5)

Overloading allows a function to accept a different number or type of arguments to be treated differently.
function reverse(x: number) :number;
function reverse(x: string) :string;
function reverse(x: number | string) :number | string | void {
    if (typeof x === 'number') {
        return Number(x.toString().split(' ').reverse().join(' '));
    } else if (typeof x === 'string') {
        return x.split(' ').reverse().join(' '); }}Copy the code

class

Decorator:

  • publicA modified property or method is public and can be accessed anywhere. Properties and methods default.
  • privateA modified property or method is private and cannot be accessed outside the class that declares it.
  • protectedA modified property or method is protected, and it andprivateSimilarly, except that it is also accessible in subclasses
class Person {
  // Default is public
  public name: string;
  static ajaxName: string = "ajaxNameSpace"; // Static properties

  constructor(n: string) {
    this.name = n;
  }

  // Static methods can access static properties
  static ajax() {
    return Person.ajaxName;
  }

  run(): void {
    console.log(this.name);
  }

  // Polymorphism: the parent defines the interface but does not implement it. Instead, the class that integrates it implements the functionality
  // Each subclass has a different representation
  size(): number {
    return 100; }}class Child extends Person {
  private age: number = 100;
  readonly school = Peking University Affiliated Primary School; // The read-only property
  // Super is equivalent to calling the parent constructor
  // Initialize the superclass
  constructor(n: string) {
    super(n);
  }

  protected work(): string {
    return "work";
  }

  run(): void {
    console.log("child run" + this.work()); }}var c1 = new Child("zhangsan");

// The ts layer is not accessible, but it will work if it is escaped as ES5, remember: ts is only a type constraint
// console.log(c1.work());
// console.log(c1.age);


// Abstract classes are used to define standards
abstract class National {
  // Abstract methods can only appear in abstract classes. Abstract classes can only be implemented by inheritance and cannot be instantiated directly
  abstract language(): any;
}

class China extends National {
  public lan: string = "Chinese";
  language() {
    return this.lan; }}var ch = new China();

Copy the code

interface

Interface: specification of behavior and actions that constrain methods in batches.

And abstract class difference:

  • An abstract class can have an implementation of a method, but the interface is completely abstract; there is no implementation of a method.
  • A subclass can inherit only one abstract class, and an interface can have multiple implementations.
  • An abstract method could bepublic.protected, but the interface can only bepublicBy default;
  • Abstract classes can have constructors, but interfaces cannot
// Attribute interface constraint JSON
interface FullName {
  firstName: string;
  secondName: string; age? :number;  // Optional attributes
}

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

// The type returned by the constraint function type is also string
interface encrypt {
  (key: string.value: number) :string;
}

// The type interface of a class is similar to that of an abstract class
interface Animal {
  name: string;
  eat(n: string) :void;
}

// An inherited implementation of the interface
interface Cattype extends Animal {
  color: string;
  say(): string;
}

// 
interface Light {
    lightOn(): void;
    lightOff(): void;
}


// Interface extension: Interfaces can inherit interfaces, well understood, coupling multiple interfaces to implement an aggregate interface
interface Alarm {
    alert(): void;
}

interface LightableAlarm extends Alarm {
    lightOn(): void;
    lightOff(): void;
}

// Do not use the interface
function printLabel(labelInfo: { labels: string }) :void {
  console.log(labelInfo);
}

// Use the interface
function printLabel2(name: FullName) :void {
  console.log("=====printLabel2", name);
}


function ajax(config: ajaxConfig) {
  var xhr = new XMLHttpRequest();
  xhr.open(config.type, config.url);
  xhr.send(config.data);
  xhr.onload = function (res) {
    console.log(res);
  };
}


// Interface of function type
// Implement the encrypted function type interface based on the encrypt interface
var md5: encrypt = function (key: string, value: number) :string {
  return window.btoa(key) + value;
};


// Class implements two interfaces
class Dog implements Animal.Light {
  public name: string = "little kitty";
  eat(food: string) :void {
    console.log(this.name + "eat=", food);
  }
   lightOn() {
      console.log('Car light on');
   }
   lightOff() {
      console.log('Car light off'); }}Copy the code

The generic

Generics is a feature that defines a function, interface, or class without specifying a specific type in advance, but instead specifies the type when it is used.

Addresses reusability of class interface methods and support for non-specific data types.

// 1: generic function

// The string and number types are both supported. What type is passed in is returned
// 
      
        indicates generics
      
// Compare generics to any: there is type verification

function getData<T> (value: T) :T {
  return value;
}
// getData<number>(100);


function getLength<T> (arr: T[]) :T[] {
  console.log(arr.length); // must be exist;
  return arr;
}
// getLength<number>([1, 2]);

// 1: generic class

// This type is passed in when instantiating
class MinClass<T> {
  list: T[] = [];
  add(value: T): void {
    this.list.push(value);
  }
  min(): T {
    return this.list.sort()[0]; }}// var m1 = new MinClass<number>();
// m1.add(10);
// m1.add(20);
// m1.add(2);
// m1.add(21);
// m1.add(1);
// m1.add(9);
// console.log(m1.min());

// 3: generic interface
interface ConfigData {
  // (value: string, key: number): string;
  <T>(value: T): T;
}
var gd: ConfigData = function <T> (value: T) :T {
  return value;
};

interface GenericIdentityFn<T> {
  (arg: T): T;
}
var myIdentity: GenericIdentityFn<number> = function <T> (arg: T) :T {
  return arg;
};

/** * Implementation case: consider the class as a parameter constraint type, so we know exactly which generic type is being used */

// Define a user class: implement a mapping to a database field
class User {
  username: string | undefined;
  passwd: string | undefined;
  constructor(u: string, p: string) {
    this.username = u;
    this.passwd = p; }}/ / class
class Arcticle {
  title: string | undefined;
  desc: string | undefined; status? :number = 0;
  constructor(t: string, d: string, s: number = 0) {
    this.title = t;
    this.desc = d;
    this.status = s; }}// Database implementation encapsulation class
class MysqlDb<T> {
  // Pass the class as an argument
  add(data: T): boolean {
    console.log(data);
    return true; }}var u = new User("zhangsan"."231231");
var arc = new Arcticle("Eat"."The description of the meal.");

// var db = new MysqlDb<User>();
var db = new MysqlDb<Arcticle>();

db.add(arc);
Copy the code

Case: implementation of a mysql and MONDB business layer encapsulation

/** * package a mysql and Mongdb package */
const store: any = {};

/ / curd interface
interface DBI<T> {
  add(data: T): boolean;
  update(d1: T, d2: number) :boolean;
  delete(d: number) :boolean;
  get(id: number) :any[];
}

// To implement a generic interface, this class must also be generic
class Mysql<T> implements DBI<T> {
  add(data: any) :boolean {
    console.log(data);
    let len = Object.keys(store);
    let id = len.length + 1;
    store[id] = data;
    return true;
  }
  update(d1: any.d2: number) :boolean {
   return true;
  }
  delete(d: number) :boolean {
    return true;
  }
  get(id: number) :any[] {
    returnstore[id]; }}// Define a user class to map to the database
class Users {
  username: string | undefined;
  passwd: number | undefined;
  constructor(u: string, p: number) {
    this.username = u;
    this.passwd = p; }}var p1 = new Users("zhangsan".123123123);
var p2 = new Users("zhaosi".11111);

var db2 = new Mysql<Users>();
db2.add(p1);

Copy the code

The namespace

One of the most explicit purposes of namespaces is to solve the problem of duplicate names.

///

com.ts:

// The namespace is treated as a module
export namespace A {
  interface Animal {
    name: string;
    eat(): void;
  }

  export class Dog2 implements Animal {
    name: string;
    constructor(n: string) {
      this.name = n;
    }

    eat() {
      console.log("==========dog eat====="); }}export class Cat implements Animal {
    name: string;
    constructor(n: string) {
      this.name = n;
    }

    eat() {
      console.log("==========cat eat====="); }}}Copy the code

index.ts:

import { A } from "./com";
var cc = new A.Cat("bb");
Copy the code

A decorator

With the introduction of classes in TypeScript and ES6, there are scenarios where we need additional features to support annotating or modifying classes and their members. Decorators provide a way for us to add annotations to class declarations and members using metaprogramming syntax.

To enable the experimentalDecorators feature, you must enable the experimentalDecorators compiler option on the command line or in tsconfig.json.

A decorator is a special type of declaration that can be attached to a class declaration, method, accessor, property, or parameter. , divided into ordinary decorator and decorator factory (can be transmitted).

// A decorator in ts is a method that can inject class method property arguments

Param: the current class Animal
function logClass(param: any) {
  param.prototype.log = function () {
    console.log("log====");
  };
}
@logClass
class Animal{}// Decorator factory
function appConfig(param: string) {
  return function (target: any) {
    // console.log(target); // HttpClient
    // console.log(param); // Manually passed parameter: http://www.baidu.com/
  };
}

@appConfig("http://www.baidu.com/")
class App {}// The property decorator is used to decorate the property. There are two parameters
function changeUrl(parm: string) {
  // Target decorated class atRR decorated properties
  return function (target: any, attr: any) {
    console.log(target, attr);
    target[attr] = parm;
  };
}

class App2{
   @changeUrl("http://git.100tal.com/")
   public url: any | undefined;
}


// Method decorator: Decorates methods
function get(param: any) {
 // fname The name of the function getData
 // Target: object HttpClient
 // Desc: freely: true,enumerable: true,value: ƒ (),writable: true

return function (target: any, fname: string, desc: any) {    
    // Overwrite the decorated function so that it is no longer executed
    var oMthod = desc.value; // === getData
    desc.value = function (. args:any) {
      // args captures the arguments of the outer decorated function [100, 200, 300]
      args = args.map((i: any) = > String(i));
      console.log("xxx", args);

      // Do not override but extend the previous method, so both will execute
      oMthod.apply(this, args);
    };
  };
}

class HttpClient {
  public url: any | undefined;
  constructor() {}

  @get(100)
  getData() {
    console.log("getData===".this.url); }}var http: any = new HttpClient();
http.getData(100.200.300);
Copy the code