1. What is typescript

  • Typescript is an open source programming language developed by Microsoft
  • Typescript is a superset of Javascript and follows the latest ES5/ES6 specifications. TypeScript extends Javascript syntax
  • TypeScript is more like back-end Java, C# and other object-oriented languages that allow JS to develop large enterprise applications
  • More and more projects are based on TS, such as VSCode, Angular6, Vue3, React16
  • The type system provided by TS helps us to provide richer syntactic hints as we write code
  • Many online errors can be avoided by checking the type system during the compile phase before creation

2. Install and compile TypeScript

2.1 installation

cnpm i typescript -g
Copy the code
tsc helloworld.ts
Copy the code

2.2 Vscode + TypeScript

2.2.1 Generating a Configuration file

tsc --init
Copy the code
{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5'.'ES2015'.'ES2016'.'ES2017'.'ES2018' or 'ESNEXT'. Specifies the target version */ of ECMAScript"module": "commonjs",                     /* Specify module code generation: 'none'.'commonjs'.'amd'.'system'.'umd'.'es2015', or 'ESNext'. Specifies how module code is generated */ //"lib": [],                             /* Specify library files to be included inThe compilation. Specifies the compilation files to include when compiling */ //"allowJs": true, /* Allow javascript files to be compiled. Allow compiling JS files */ //"checkJs": true,                       /* Report errors in.js files. include errors in js */ //"jsx": "preserve",                     /* Specify JSX code generation: 'preserve'.'react-native', or 'react'Specifies whether JSX code is generated in a reserved or react-native or react*/ //"declaration": true,                   /* Generates corresponding '.d.ts'Generate the corresponding type declaration file */ //"declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts'Generate sourcemap*/ // for each type declaration file"sourceMap": true,                     /* Generates corresponding '.map'Generate the corresponding map file */ //"outFile": ". /", /* Concatenate and emit output to single file. Merge and output the compiled content to a file */ //"outDir": ". /", /* Redirect output structure to the directory. Output as the original structure to the target directory */ //"rootDir": ". /", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. Specify the root directory of the input file and use --outDir to control the directory structure of the output */ //"composite": true, /* Enable project compilation */ //"removeComments": true, /* Do not emit comments to output. Remove comment */ //"noEmit": true, /* Do not emit outputs. */ //"importHelpers": true,                 /* Import emit helpers from 'tslib'. * / / /"downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'Provide pairs when the target is ES5 or ES3forFull support for iterators in -of, extension operators, and destruct assignments */ //"isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule').r translates each file into a separate module */ /* Strict Type-Checking Options */ //"strict": true,                           /* Enable all strict type- Checking options. Enable full strict type checking */ //"noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any'Type. Cannot use the implicit any type */ //"strictNullChecks": true, /* Enable strict null checks. Enable strict NULL checking */ //"strictFunctionTypes": true,           /* Enable strict checking of functionTypes. Enable strict function type checking */ //"strictBindCallApply": true,           /* Enable strict 'bind'.'call', and 'apply'Methods on functionsbindCall and apply methods */ //"strictPropertyInitialization": true,  /* Enable strict checking of property initialization inEnable initialization property checking on classes */ //"noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any'Type. Error */ // when calling this in the default any"alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each sourceUse strict*/ /* Additional Checks */ //"noUnusedLocals": true, /* Report errors on unused locals. Error */ // reporting unused local variables"noUnusedParameters": true, /* Report errors on unused parameters. Error reported for unused parameter */ //"noImplicitReturns": true,             /* Report error when not all code paths in function returnError */ // when not all code paths have a return value"noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases inSwitch Statement. There is no substitute in the switch expressioncase*/ /* Module Resolution Options */ //"moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic'(TypeScript pre-1.6). Specify module resolution strategy node classic*/ //"baseUrl": ". /", /* Base directory to resolve non-absolute module names. Base path */ // when resolving non-absolute path module names"paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.set of some paths */ //"rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. A list of root directories that are used at runtime to merge contents */ //"typeRoots": [],                       /* List of folders to include typeDefinitions from. List of folders containing type declarations */ //"types": [],                           /* Type declaration files to be included inCompilation. Type declarations included at compilation time */ //"allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. Allow default import when there is no default export. This has no effect on code execution, but only on type checking"esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. * / / /"preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ //"sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of sourceLocations. Specify the location of the TS file */ //"mapRoot": "",                         /* Specify the location wheredebugger should locate map files instead of generated locations. Specify the location where the map file is stored */ //"inlineSourceMap": true,               /* Emit a single file with sourcemaps instead of having a separate file. The source file and sourcemap file are in the same file, rather than putting the map file in a separate file */ //"inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap'To be set. Source file and sourcemap file are in the same file */ /* Experimental Options */ //"experimentalDecorators": true,        /* Enables experimental support forES7 decorators. */ //"emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
  }
}
Copy the code

2.2.2 Compiling

tsc 
Copy the code

2.2.3 vscode run

  • Terminal->Run Task-> TSC :build
  • Terminal->Run Task-> TSC :watch

2.2.4 npm scripts

  • NPM run actually calls the local Shell to execute the corresponding script value, so it is theoretically compatible with all bash commands
  • The Shell is /bin/sh on UNIX-like systems and cmd.exe on Windows

2.2.5 PATH of NPM scripts

  • NPM Run presets the PATH to the node_modules/.bin directory in the package

3. Data type

3.1 Boolean type (Boolean)

let married: boolean=false;
Copy the code

3.2 Number Type

let age: number=10;
Copy the code

3.3 String Type (String)

let firstname: string='zfpx';
Copy the code

3.4 Array Types

letArr2: number [] = (4 and 6);letArr3: Array < number > =,8,9 [7];Copy the code

3.5 Tuple Types

  • In TypeScript’s base type, a Tuple represents a known typeThe number ofandtypeAn array of
let zhufeng:[string,number] = ['zhufeng', 5]; zhufeng[0].length; zhufeng[1].toFixed(2);Copy the code
tuples An array of
Each term can be of a different type Everything is of the same type
There are predefined lengths No length limit
Used to represent a fixed structure Used to represent a list
const animal:[string,number,boolean] = ['zhufeng'Ten,true];
Copy the code

3.6 Enumeration Types (enum)

  • Consider all possible values of a variable in advance, and try to represent each value in terms of natural language words
  • Such as gender, month, week, color, unit, education

3.6.1 Common Enumeration

Enum Gender{GIRL, BOY} console.log(' li Li is${Gender.BOY}`); Console. log(' Han Meimei is${Gender.GIRL}`); Enum Week{MONDAY=1, TUESDAY=2} console.log(' Today is Week${Week.MONDAY}`);
Copy the code

3.6.2 Constant enumeration

  • Constant enumerations differ from ordinary enumerations in that they are removed at compile time and cannot contain computed members.
  • If a computed member is included, an error will be reported at compile time
const enum Colors {
    Red,
    Yellow,
    Blue
}

let myColors = [Colors.Red, Colors.Yellow, Colors.Blue];
Copy the code
const enum Color {Red, Yellow, Blue = "blue".length};
Copy the code

3.7 Any Type (Any)

  • anyYou can assign to any type
  • Used when a third-party library does not provide a type fileany
  • When type conversion is difficult
  • The data structure is too complex to define
let root:any=document.getElementById('root');
root.style.color='red';
Copy the code
let root:(HTMLElement|null)=document.getElementById('root'); root! .style.color='red'; // The non-empty assertion operatorCopy the code

3.8 null, and undefined

  • Null and undefined are subtypes of other types and can be assigned to other types, such as numeric types. In this case, the assigned type becomes null or undefined
  • strictNullChecksParameter is used in the new strict null-check mode. In strict null-check mode, null and undefined values do not belong to either type and can only be assigned to their own type or to any
let x: number;
x = 1;
x = undefined;    
x = null;   

let y: number | null | undefined;
y = 1;
y = undefined;   
y = null;   
Copy the code

3.9 void type

  • Void means there is no type
  • When a function returns no value, TS assumes that its return value is of type void.
function greeting(name:string):void {
    console.log('hello',name); // When we declare a variable of type void, its non-strict mode (strictNullChecks:false// Strict mode (strictNullChecks:true) only return undefined //return null;
    //return undefined;
}
Copy the code

3.10 never type

Never is a subtype of another type (null undefined) and represents a value that will not occur

3.10.1

  • As a return value type for a function that does not return
// A function that returns never must have a point that is unreachablefunction error(message: string): never {
    throw new Error(message);
}
let result1 = error('hello'); // The return value is never inferred from the typefunction fail() {
    return error("Something failed");
}
letresult = fail(); // A function that returns never must have a point that is unreachablefunction infiniteLoop(): never {
    while (true) {}}Copy the code

3.10.2 strictNullChecks

  • In TS, null and undefined are valid values for any type, so there is no way to correctly check if they are being used incorrectly. So TS introduced the strictNullChecks model
  • With the introduction of –strictNullChecks, null and undefined can be detected in this mode. So TS needs a new bottom type. So we introduced never.
// Compiled with --strictNullChecks
function fn(x: number | string) {
  if (typeof x === 'number') {
    // x: number 类型
  } else if (typeof x === 'string') {// x: string}else{// x: never // --strictNullChecks will not be executed, x will not be observed}}Copy the code

3.10.3 Differences between never and void

  • Void can be assigned to null and undefined types. Never is a type that does not contain a value.
  • A function with a void return type will work fine. A function with a return type of never cannot return normally, cannot terminate, or throws an exception.

3.11 Type inference

  • The ability in a programming language to automatically deduce the type of a value, a feature found in some strongly statically typed languages
  • An unassigned value is inferred to be of type any
  • Type inference can be used if you assign values when you define them
let username2;
username2 = 10;
username2 = 'zhufeng';
username2 = null;
Copy the code

3.12 Wrapper Object

  • There are two types of JavaScript: Primitive data types and Object types.
  • All primitive data types have no property
  • Raw data type
    • Boolean value
    • The numerical
    • string
    • null
    • undefined
    • Symbol
let name = 'zhufeng';
console.log(name.toUpperCase());

console.log((new String('zhufeng')).toUpperCase());
Copy the code
  • JavaScript makes a quick mandatory switch between the raw data type and the object type when calling a primitive data type method
let isOK: boolean = true; // Compile passedletIsOK: Boolean = Boolean(1) // Compile passedletisOK: boolean = new Boolean(1); // The compiler failed expecting the isOK to be a primitive data typeCopy the code

3.13 Union type

  • Union Types indicate that the value can be one of multiple Types
  • Only properties and methods shared by the two types can be accessed on the union type without assignment
let name: string | number;
console.log(name.toString());
name = 3;
console.log(name.toFixed(2));
name = 'zhufeng';
console.log(name.length);

export {};
Copy the code

3.14 Type assertion

  • Type assertions can specify a variable of a union type to a more specific type
  • You cannot assert that a union type does not exist
let name: string | number;
console.log((name as string).length);
console.log((name as number).toFixed(2));
console.log((name as boolean));
Copy the code

3.15 Literal types

  • You can combine strings, numbers, and Boolean literals into a union type
type ZType = 1 | 'One'|true;
let t1:ZType = 1;
let t2:ZType = 'One';
let t3:ZType = true;
Copy the code

3.16 String literals vs union types

  • The string literal type is used to restrict the value to aSeveral stringsUnion Types indicate that the value can beA variety of typesOne of the
  • String literals restrict the use of the literal to accept only a specific value. Union types do not restrict the value, only the type of the value needs to be consistent

4. The function

4.1 Definition of functions

  • You can specify the type of the argument and the type of the return value
function hello(name:string):void {
    console.log('hello',name);
}
hello('zfpx');
Copy the code

4.2 Function Expression

  • Defining function types
type GetUsernameFunction = (x:string,y:string)=>string;
let getUsername:GetUsernameFunction = function(firstName,lastName){
  return firstName + lastName;
}
Copy the code

4.3 No Return value

let hello2 = function (name:string):void {
    console.log('hello2',name);
    return undefined;
}
hello2('zfpx');
Copy the code

4.4 This parameter is optional

In TS, the function parameters and arguments must be the same. If they are different, the optional argument must be set, and the parameter must be the last one

function print(name:string,age? :number):void { console.log(name,age); }print('zfpx');
Copy the code

4.5 Default Parameters

function ajax(url:string,method:string='GET') {
    console.log(url,method);
}
ajax('/users');
Copy the code

4.6 Remaining Parameters

functionsum(... numbers:number[]) {returnnumbers.reduce((val,item)=>val+=item,0); } the console. The log (sum (1, 2, 3));Copy the code

4.7 Function Overloading

  • In Java, overloading refers to two or more functions of the same name that take different arguments
  • In TypeScript, this is done by providing multiple function type definitions for the same function
let obj: any={};
function attr(val: string): void;
function attr(val: number): void;
function attr(val:any):void {
    if (typeof val === 'string') {
        obj.name=val;
    } else {
        obj.age=val;
    }
}
attr('zfpx');
attr(9);
attr(true);
console.log(obj);
Copy the code

Class 5.

5.1 How do I define a Class

  • “strictPropertyInitialization”: true /
    Enable strict checking of class property initialization

    /

  • name! :string
class Person{ name:string; getName():void{ console.log(this.name); }}let p1 = new Person();
p1.name = 'zhufeng';
p1.getName();
Copy the code

5.2 accessor

  • In TypeScript, we can use accessors to change the reading and assignment behavior of properties in a class
  • The constructor
    • It is used to initialize the member variable properties of a class
    • Class is automatically called when an object is created
    • No return value
class User {
    myname:string;
    constructor(myname: string) {
        this.myname = myname;
    }
    get name() {
        return this.myname;
    }
    setname(value) { this.myname = value; }}let user = new User('zhufeng');
user.name = 'jiagou'; 
console.log(user.name); 
Copy the code
"use strict";
var User = /** @class */ (function () {
    function User(myname) {
        this.myname = myname;
    }
    Object.defineProperty(User.prototype, "name", {
        get: function () {
            return this.myname;
        },
        set: function (value) {
            this.myname = value;
        },
        enumerable: true,
        configurable: true
    });
    returnUser; } ()); var user = new User('zhufeng');
user.name = 'jiagou';
console.log(user.name);
Copy the code

5.3 Parameter Attributes

class User {
    constructor(public myname: string) {}
    get name() {
        return this.myname;
    }
    setname(value) { this.myname = value; }}let user = new User('zhufeng');
console.log(user.name); 
user.name = 'jiagou'; 
console.log(user.name);
Copy the code

5.4 readonly

  • The readonly variable can only be modified inThe constructorIn the initialization
  • In TypeScript, const isconstantAn identifier whose value cannot be reassigned
  • TypeScript’s type system also allows properties on interface, type, and class to be identified as readonly
  • Readonly Is actually only incompilePhase for code review. And const will be thereThe runtimeChecking (in a JavaScript runtime environment that supports const syntax)
class Animal {
    public readonlyname: string constructor(name:string) { this.name = name; } changeName(name:string){ this.name = name; }}let a = new Animal('zhufeng');
a.changeName('jiagou');
Copy the code

5.5 inheritance

  • After a subclass inherits from its parent class, instances of the subclass have the properties and methods of the parent class, which can enhance the reusability of the code
  • The common methods of the subclass are abstracted into the superclass, and their own special logic is put into the subclass to override the logic of the superclass
  • Super can call methods and properties on its parent class
class Person { name: string; // Define the properties of the instance. By default, omit the public modifier age: number; Constructor (name:string,age:number) {// constructor(name:string,age:number) {this.name=name; this.age=age; } getName():string {return this.name;
    }
    setName(name:string): void{
        this.name=name;
    }
}
class Student extends Person{
    no: number;
    constructor(name:string,age:number,no:number) {
        super(name,age);
        this.no=no;
    }
    getNo():number {
        returnthis.no; }}let s1=new Student('zfpx'10, 1); console.log(s1);Copy the code

Modifiers in class 5.6

class Father { public name: string; // Protected age: number can be accessed from any subclass within the class; Private money: number; private money: number; / / class can access, subclasses and anywhere else you can't access the constructor (name: string, age: number, money: number) {/ / this constructor. Name = name; this.age=age; this.money=money; } getName():string {return this.name;
    }
    setName(name:string): void{
        this.name=name;
    }
}
class Child extends Father{
    constructor(name:string,age:number,money:number) {
        super(name,age,money);
    }
    desc() {
        console.log(`${this.name} ${this.age} ${this.money}`); }}let child = new Child('zfpx', 10100); console.log(child.name); console.log(child.age); console.log(child.money);Copy the code

5.7 Static Properties Static methods

class Father {
    static className='Father';
    static getClassName() {
        returnFather.className; } public name: string; // constructor(name:string) {// constructor(name:string) {this.name=name; } } console.log(Father.className); console.log(Father.getClassName());Copy the code

5.8 the abstract class

  • Abstract describes an abstract concept that cannot be instantiated, only inherited
  • Unable to create an instance of abstract class
  • Abstract methods cannot be implemented in abstract classes, only in concrete subclasses of abstract classes, and must be implemented
abstract class Animal { name! :string; abstract speak():void; } class Cat extends Animal{speak(){
        console.log('Meow meow meow'); }}letanimal = new Animal(); //Cannot create an instance of an abstract class animal.speak();let cat = new Cat();
cat.speak();
Copy the code
Access control modifier private protected public
Read-only property readonly
Static attributes static
Abstract class, abstract method abstract

5.9 Abstract classes vs interfaces

  • Properties or methods that are public between classes can be abstracted into Interfaces
  • Abstract classes are base classes that other classes inherit from. They are not allowed to be instantiated. Abstract methods in an abstract class must be implemented in a subclass
  • An abstract class is essentially a class that cannot be instantiated. It can implement methods and initialize properties, while an interface can only be used for description, providing neither method implementation nor initialization of properties
  • A class can inherit from a class or abstract class, but can implement (implements) more than one interface
  • Abstract classes can also implement interfaces
abstract class Animal{
    name:string;
    constructor(name:string){
      this.name = name;
    }
    abstract speak():void;
  }
  interface Flying{
      fly():void
  }
class Duck extends Animal implements Flying{
      speak(){
          console.log('Woof woof');
      }
      fly(){
          console.log('I can fly'); }}let duck = new Duck('zhufeng');
duck.speak();
duck.fly();
Copy the code

5.10 Abstract methods

  • Abstract classes and methods do not contain concrete implementations and must be implemented in subclasses
  • Abstract methods can only appear in abstract classes
  • Subclasses can implement abstract classes in different ways
abstract class Animal{
    abstract speak():void;
}
class Dog extends  Animal{
    speak(){
        console.log('Dog woof woof');
    }
}
class Cat extends  Animal{
    speak(){
        console.log('Cat meow meow meow'); }}let dog=new Dog();
let cat=new Cat();
dog.speak();
cat.speak();
Copy the code

5.11 Override vs Overload

  • Override is when a child overrides a method inherited from a parent class
  • Overloading means providing multiple type definitions for the same function
class Animal{
    speak(word:string):string{
        return 'Action called :'+word;
    }
}
class Cat extends Animal{
    speak(word:string):string{
        return 'the cat call:+word; }}let cat = new Cat();
console.log(cat.speak('hello'));
//--------------------------------------------
function double(val:number):number
function double(val:string):string
function double(val:any):any{
  if(typeof val == 'number') {return val *2;
  }
  return val + val;
}

let r = double(1);
console.log(r);
Copy the code

5.12 Inheritance vs. polymorphism

  • A child inherits from its parent. In addition to having all the features of its parent, a child also has some more specific features
  • Polymorphism results from inheritance from different related classes that may have different responses to the same method
class Animal{
    speak(word:string):string{
        return 'Animal: '+word;
    }
}
class Cat extends Animal{
    speak(word:string):string{
        return 'Cat:'+word;
    }
}
class Dog extends Animal{
    speak(word:string):string{
        return 'Dog:'+word; }}let cat = new Cat();
console.log(cat.speak('hello'));
let dog = new Dog();
console.log(dog.speak('hello'));
Copy the code

6. Interface

  • On the one hand, interfaces can be represented in object-oriented programming asAbstraction of behaviorCan also be used to describeShape of object
  • An interface is an abstraction of the properties and methods common to some classes, which can be used to constrain the classes that implement this interface
  • A class can inherit from another class and implement multiple interfaces
  • Interfaces, like plug-ins, are used to enhance classes, and abstract classes are abstractions of concrete classes
  • A class can implement multiple interfaces, and an interface can be implemented by multiple classes, but a class can have multiple subclasses, but only one parent class

6.1 interface

  • You can separate each item in interface with a semicolon or a comma, or you can do nothing at all, right

6.1.1 Shapes of objects

Interface Speakable{speak():void; Speakable{Speakable ():void; Speakable{Speakable ():void; name? :string; / /? Represents an optional attribute}let speakman:Speakable = {
    speak(){},// there is an error in the name, age// there is an error in the name, age}Copy the code

6.1.2 Abstraction of behavior

Interface Speakable{speak():void; // Speakable{Speakable ():void; } interface Eatable{eat():void} class Person implements Speakable,Eatable{speak(){
        console.log('the Person talking');
    }
    eat(){}
}
class TangDuck implements Speakable{
    speak(){
        console.log('TangDuck talk');
    }
    eat(){}
}
Copy the code

6.1.3 Arbitrary attributes

// You can use '[propName:string]:any' when you can't know in advance what new properties are available. The propName name is any interface Person {readonly id: number;
  name: string;
  [propName: string]: any;
}

let p1 = {
  id:1,
  name:'zhufeng',
  age:10
}
Copy the code

6.2 Interface Inheritance

  • An interface can inherit from another interface
interface Speakable {
    speak(): void
}
interface SpeakChinese extends Speakable {
    speakChinese(): void
}
class Person implements SpeakChinese {
    speak() {
        console.log('Person')}speakChinese() {
        console.log('speakChinese')}}Copy the code

6.3 readonly

  • Defining the read-only attribute with readonly avoids overwriting the object’s value because of multiple collaboration or project complexity
interface Person{
  readonly id:number;
  name:string
}
let tom:Person = {
  id :1,
  name:'zhufeng'
}
tom.id = 1;
Copy the code

6.4 Function Type Interface

  • Constrains the parameters and return values passed to the method
interface discount{
  (price:number):number
}
let cost:discount = function(price:number):number{
   return price * .8;
}
Copy the code

6.5 Indexable Interfaces

  • Constrains arrays and objects
  • UserInterface: as long as the index is of type number, then the value must be of type String
  • UserInterface2 indicates that as long as index is of type String, then the value must be of type String
interface UserInterface {
  [index:number]:string
}
let arr:UserInterface = ['zfpx1'.'zfpx2'];
console.log(arr);

interface UserInterface2 {
  [index:string]:string
}
let obj:UserInterface2 = {name:'zhufeng'};

Copy the code

6.6 class interface

  • Constraints on classes
interface Speakable {
    name: string;
    speak(words: string): void
}
class Dog implements Speakable {
    name!: string;
    speak(words:string) {
        console.log(words);
    }
}
let dog = new Dog();
dog.speak('Woof woof');
Copy the code

6.7 Constructor types

  • In TypeScript, we use interfaces to describe classes
  • You can also use the special new() keyword in the interface to describe the constructor type of the class
class Animal{
  constructor(public name:string){
  }
}
interface WithNameClass{
  new(name:string):Animal
}
function createAnimal(clazz:WithNameClass,name:string){
   return new clazz(name);
}
let a = createAnimal(Animal,'zhufeng');
console.log(a.name);
Copy the code

7. 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
  • The genericTScope is limited to internal use of functions

7.1 Generic functions

  • First, let’s implement a function, createArray, that creates an array of specified lengths and populates each item with a default value
function createArray(length: number, value: any): Array<any> {
  let result: any = [];
  for (let i = 0; i < length; i++) {
    result[i] = value;
  }
  return result;
}
let result = createArray(3,'x');
console.log(result);
Copy the code

Generics are used

function createArray<T>(length: number, value: T): Array<T> {
    let result: T[] = [];
    for (let i = 0; i < length; i++) {
      result[i] = value;
    }
    return result;
  }
let result = createArray2<string>(3,'x');
console.log(result);
Copy the code

7.2 class array

  • Array-like Objects are not Array types, for examplearguments
functionsum(... parameters: number[]) {let args: IArguments = arguments;
    for (let i = 0; i < args.length; i++) {
        console.log(args[i]);
    }
}
sum(1, 2, 3);

let root = document.getElementById('root');
let children: HTMLCollection = (root as HTMLElement).children;
children.length;
let nodeList: NodeList = (root as HTMLElement).childNodes;
nodeList.length;
Copy the code

7.3 a generic class

class MyArray<T>{
    private list:T[]=[];
    add(value:T) {
        this.list.push(value);
    }
    getMax():T {
        let result=this.list[0];
        for (leti=0; i<this.list.length; i++){if(this.list[i]>result) { result=this.list[i]; }}returnresult; }}let arr=new MyArray();
arr.add(1); arr.add(2); arr.add(3);
let ret = arr.getMax();
console.log(ret);
Copy the code

7.5 Generic interfaces

  • Generic interfaces can be used to constrain functions
interface Calculate{
  <T>(a:T,b:T):T
}
let add:Calculate = function<T>(a:T,b:T){
  returna; } the add < number > (1, 2);Copy the code

7.6 Multiple Type parameters

  • There can be more than one generics
function swap<A,B>(tuple:[A,B]):[B,A]{
  return [tuple[1],tuple[0]];
}
let swapped = swap<string,number>(['a', 1)); console.log(swapped); console.log(swapped[0].toFixed(2)); console.log(swapped[1].length);Copy the code

7.7 Default generic types

function createArray3<T=number>(length: number, value: T): Array<T> {
  let result: T[] = [];
  for (let i = 0; i < length; i++) {
    result[i] = value;
  }
  return result;
}
let result2 = createArray3(3,'x');
console.log(result2);
Copy the code

7.8 Generic Constraints

  • When you use a generic type in a function, you do not have access to the properties or methods of the type because you do not know the type in advance.
functionlogger<T>(val: T) { console.log(val.length); LengthWise {length: number} : LengthWise {length: number} : LengthWise {length: number} : LengthWise {length: numberfunction logger2<T extends LengthWise>(val: T) {
    console.log(val.length)
}
logger2('zhufeng');
logger2(1);
Copy the code

7.9 Generic interfaces

  • You can also specify generics when you define an interface
interface Cart<T>{
  list:T[]
}
let cart:Cart<{name:string,price:number}> = {
  list:[{name:'zhufeng',price:10}]
}
console.log(cart.list[0].name,cart.list[0].price);
Copy the code

7.10 Generic type aliases

  • Generic type aliases can express more complex types
type Cart<T> = {list:T[]} | T[];
let c1:Cart<string> = {list:['1']};
let c2:Cart<number> = [1];
Copy the code

7.11 Generic interfaces vs generic type aliases

  • The interface creates a new name that can be called anywhere else. A type alias does not create a new name, for example, if an error message is reported, the alias is not used
  • Type aliases cannot be extends and implements, so we should try to use interfaces instead of type aliases
  • Type aliases are more appropriate when we need to use associative or tuple types

8. Structure type system

8.1 Interface Compatibility

  • If the passed variable does not match the declared type, TS performs a compatibility check
  • The principle isDuck-CheckAttribute variables declared in the target type are compatible as long as they exist in the source type
interface Animal { name: string; age: number; } interface Person { name: string; age: number; Gender: number} // To determine if the target type 'Person' is compatible with the input source type 'Animal'function getName(animal: Animal): string {
    return animal.name;
}

let p = {
    name: 'zhufeng', age: 10, gender: 0 } getName(p); // The compatibility comparison between two variables is made only when the parameters are passed. The compatibility comparison is not made when the values are assignedlet a: Animal = {
    name: 'zhufeng',
    age: 10,
    gender: 0
}
Copy the code

8.2 Compatibility with Basic Types

// Basic data types also have compatibility checkslet num : string|number;
let str:string='zhufeng'; num = str; // Assign to a string variable as long as there is a toString() methodlet num2 : {
  toString():string
}

let str2:string='jiagour';
num2 = str2;
Copy the code

8.3 Class compatibility

  • In TS is the structure type system, which only compares the structure and does not care about the type
class Animal{
    name:string
}
class Bird extends Animal{
   swing:number
}

let a:Animal;
a = new Bird();

letb:Bird; B = new Animal();Copy the code
Class Bird extends Animal{name:string} class Bird extends Animal{}let a:Animal;
a = new Bird();

let b:Bird;
b = new Animal();

Copy the code
Class Animal{name:string} class Bird{name:string} class Animal{name:string}let a:Animal ;
a = new Bird();
let b:Bird;
b = new Animal();
Copy the code

8.4 Function compatibility

  • When you compare functions, you first compare the parameters of the function and then the return value of the function

8.4.1 Comparing Parameters

type sumFunc = (a:number,b:number)=>number;
let sum:sumFunc;
function f1(a:number,b:number):number{
  returna+b; } sum = f1; // You can omit an argumentfunction f2(a:number):number{
   returna; } sum = f2; // Two parameters can be omittedfunction f3():number{
    return0; } sum = f3; // One more parameter is not acceptablefunction f4(a:number,b:number,c:number){
    return a+b+c;
}
sum = f4;
Copy the code

8.4.2 Comparing Return Values

type GetPerson = ()=>{name:string,age:number};
letgetPerson:GetPerson; // The return value is finefunction g1() {return {name:'zhufeng',age:10}; } getPerson = g1; // The return value can have one more attributefunction g2() {return {name:'zhufeng',age:10,gender:'male'}; } getPerson = g2; // The return value is missing one attributefunction g3() {return {name:'zhufeng'}; } getPerson = g3; // Because it is possible to call the method getPerson().age.tofixed () on the return value;Copy the code

8.5 Covariant of function parameters

  • The target is ok if it is compatible with the source
type LogFunc = (a:number|string)=>void;
let log:LogFunc;

function log1(a:number|string|boolean){ console.log(a); } // The target is ok if it is compatible with the sourcelog = log1;
Copy the code

8.6 Generic compatibility

  • Generics are judged for compatibility by the specific type first and then by compatibility
Empty<T>{} interface Empty<T>{} interface Empty<T>{}letx! :Empty<string>;lety! :Empty<number>; x = y; Interface NotEmpty<T>{data:T}letx1! :NotEmpty<string>;lety1! :NotEmpty<number>; x1 = y1; Interface NotEmptyString{data:string} interface NotEmptyNumber{data:number}letxx2! :NotEmptyString;letyy2! :NotEmptyNumber; xx2 = yy2;Copy the code

8.7 Enumeration compatibility

  • Enumerated types are compatible with numeric types, and numeric types are compatible with enumerated types
  • Different enumeration types are incompatible
Enum Colors {Red,Yellow}let c:Colors;
c = Colors.Red;
c = 1;
c = '1'; // Enumeration values can be assigned to numberslet n:number;
n = 1;
n = Colors.Red;
Copy the code

9. Type protection

  • Type protection is expressions that ensure the type of a variable in a scope at compile time by using type information
  • Type protection is the ability to determine the type in a branch by keyword

9.1 Typeof protection

function double(input: string | number | boolean) {
    if (typeof input === 'string') {
        return input + input;
    } else {
        if (typeof input === 'number') {
            return input * 2;
        } else {
            return! input; }}}Copy the code

9.2 Instanceof type protection

class Animal { name! : string; } class Bird extends Animal { swing! : number }function getName(animal: Animal) {
    if (animal instanceof Bird) {
        console.log(animal.swing);
    } else{ console.log(animal.name); }}Copy the code

9.3 null protection

  • If it’s onstrictNullChecksOption, you cannot call methods and properties on a variable that may be null
functionGetFirstLetter (s: string | null) {/ / the first way is combined with null judgmentsif (s == null) {
        return ' '; } / / the second treatment is to increase a or s = s | |' ';
    returns.charAt(0); } // It does not handle complex judgments and requires a non-null assertion operatorfunction getFirstLetter2(s: string | null) {
    function log() { console.log(s! .trim()); } s = s ||' ';
    log(a);return s.charAt(0);
}
Copy the code

9.4 Chain judgment operators

  • A chain judgment operator is an operator that checks for the existence of a property and then attempts to access it. Its symbol is? .
  • What if the operand to the left of the operator? . Evaluates to undefined or NULL, then the expression evaluates to undefined. Otherwise, the target property access, method or function call normally triggers.
a? .b; // Return undefined if a is null/undefined, otherwise return the value of A.B. A == null? undefined : a.b; a? .[x]; // If a is null/undefined, return undefined; otherwise return the value a[x] a == null? undefined : a[x]; a? .b(); // If a is null/undefined, return undefined a == null? undefined : a.b(); // if a.b() does not function, throw a type error exception, otherwise calculate a.b() result a? . (); // If a is null/undefined, return undefined a == null? undefined : a(); // If A is not A function, it will throw A type errorCopy the code

The chain determination operator is still in stage1 and is not supported by TS for the time being

9.5 Identifiable union types

  • Is a technique to use common fields in a union type for type protection
  • Different values of the same field are recognizable
interface WarningButton{
  class:'warning',
  text1:'change'
}
interface DangerButton{
  class:'danger',
  text2:'delete'
}
type Button = WarningButton|DangerButton;
function getButton(button:Button){
 if(button.class=='warning'){
  console.log(button.text1);
 }
 if(button.class=='danger'){ console.log(button.text2); }}Copy the code

9.6 In operator

  • The in operator can be used to determine parameter types
interface Bird {
    swing: number;
}

interface Dog {
    leg: number;
}

function getNumber(x: Bird | Dog) {
    if ("swing" in x) {
      return x.swing;
    }
    return x.leg;
}
Copy the code

9.7 User-defined type Protection

  • Type protection in TypeScript is essentially expressions that check the type information at run time to make sure that the type in a scope is as expected
  • To customize a type guard, simply define a function for the type guard, whose return value is a type predicate
  • The syntax for a type predicate isparameterName is TypeIn this form, whereparameterNameMust be a parameter name in the current function signature
interface Bird { swing: number; } interface Dog { leg: number; } // There are no identical fields to define a type protection functionfunction isBird(x:Bird|Dog): x is Bird{
  return (<Bird>x).swing == 2;
  return (x as Bird).swing == 2;
}
function getAnimal(x: Bird | Dog) {
  if (isBird(x)) {
    return x.swing;
  }
  return x.leg;
}
Copy the code

10. Type transformation

10.1 Crossover Types

  • Intersection Types represent the merging of multiple Types into a single type
    interface Bird {
      name: string,
      fly(): void
    }
    interface Person {
      name: string,
      talk(): void
    }
    type BirdPerson = Bird & Person;
    let p: BirdPerson = { name: 'zhufeng'.fly() {},talk() {}}; p.fly; p.name p.talk;Copy the code

10.2 typeof

  • Can get the type of a variable
// First define the type, then define the variabletype People = {
    name:string,
    age:number,
    gender:string
}
let p1:People = {
    name:'zhufeng',
    age:10,
    gender:'male'
}
Copy the code
// First define the variable, then define the typelet p1 = {
    name:'zhufeng',
    age:10,
    gender:'male'
}
type People = typeof p1;
function getName(p:People):string{
    return p.name;
}
getName(p1);
Copy the code

10.3 Index Access Operators

  • Subtypes of a type can be obtained by []
interface Person{
    name:string;
    age:number;
    job:{
        name:string
    };
    interests:{name:string,level:number}[]
}
let FrontEndJob:Person['job'] = {
    name:'Front End Engineer'
}
let interestLevel:Person['interests'] [0] ['level'] = 2;
Copy the code

10.4 keyof

  • Index type Indicates the query operator
interface Person{
  name:string;
  age:number;
  gender:'male'|'female'; } / /type PersonKey = 'name'|'age'|'gender';
type PersonKey = keyof Person;

function getValueByKey(p:Person,key:PersonKey){
  return p[key];
}
let val = getValueByKey({name:'zhufeng',age:10,gender:'male'},'name');
console.log(val);
Copy the code

10.5 Mapping Types

  • When defining, use the in operator to batch define the properties of the type
interface Person{
  name:string;
  age:number;
  gender:'male'|'female'; } // Make the properties of an interface optional in bulktype PartPerson = {
  [Key inkeyof Person]? :Person[Key] }letp1:PartPerson={}; // You can also use genericstype Part<T> = {
  [key inkeyof T]? :T[key] }let p2:Part<Person>={};
Copy the code

10.6 Types of Built-in Tools

  • There are several types of tools built into TS to help us make better use of the type system

    10.6.1 Partial

  • Partial can change an passed property from non-optional to optional, as follows:
type Partial<T> = { [P inkeyof T]? : T[P] }; interface A { a1: string; a2: number; a3: boolean; }typeaPartial = Partial<A>; const a: aPartial = {}; // No error will be reportedCopy the code

10.6.2 Required

  • Required makes an option in an passed attribute mandatory, using -? Modifier.
//type Required<T> = { [P inkeyof T]-? : T[P] }; interface Person{ name:string; age:number; gender? :'male'|'female'; } / * * *type Require<T> = { [P inkeyof T]-? : T[P] }; * /let p:Required<Person> = {
  name:'zhufeng',
  age:10,
  //gender:'male'
}
Copy the code

10.6.3 Readonly

  • Readonly is implemented by adding the Readonly modifier to each of the attributes passed in.
interface Person{ name:string; age:number; gender? :'male'|'female'; } / /type Readonly<T> = { readonly [P in keyof T]: T[P] };
let p:Readonly<Person> = {
  name:'zhufeng',
  age:10,
  gender:'male'
}
p.age = 11;
Copy the code

10.6.4 Pick

  • Pick helps us to return an item from an passed property
interface Animal {
  name: string;
  age: number;
}
/**
 * From T pick a set of properties K
 * type Pick<T, K extends keyof T> = { [P inK]: T[P] }; */ // select name from Animaltype AnimalSub = Pick<Animal, "name">; //{ name: string; }
let a:AnimalSub = {
    name:'zhufeng',
    age:10
}
Copy the code

10.6.5 Control of mapping type modifiers

  • TypeScript adds control over mapping type modifiers
  • Specifically, onereadonly?Modifiers can be prefixed within a mapping type+-To indicate that the modifier should be added or removed
  • Some of the built-in utility types in TS take advantage of this feature (Partial, Required, Readonly…) Here we can refer to the Partial and Required implementations

10.7 Condition Types

  • Logical branches can be added when generics are defined, making them more flexible in the future

10.7.1 Defining a condition type

interface Fish { name: string } interface Water { name: string } interface Bird { name: string } interface Sky { name: String} // Ternary operatortype Condition<T> = T extends Fish ? Water : Sky;
let condition: Condition<Fish> = { name: 'water' };
Copy the code

10.7.2 Distribution of a condition type

interface Fish {
    fish: string
}
interface Water {
    water: string
}
interface Bird {
    bird: string
}
interface Sky {
    sky: string
}

type Condition<T> = T extends Fish ? Water : Sky;
//(Fish extends Fish ? Water : Sky) | (Bird extends Fish ? Water : Sky)
// Water|Sky
let condition1: Condition<Fish | Bird> = { water: 'water' };
let condition2: Condition<Fish | Bird> = { sky: 'the sky' };
Copy the code

10.7.3 Types of built-in conditions

  • TS has some common conditional types built in, which can be viewed in lib.es5.d.ts:
10.7.3.1 Exclude
  • Exclude U from the types to which T can be assigned
    type  E = Exclude<string|number,string>;
    let e:E = 10;
    Copy the code
10.7.3.2 Extract
  • Extract U from the type that T can allocate
    type  E = Extract<string|number,string>;
    let e:E = '1';
    Copy the code
10.7.3.3 NonNullable
  • Exclude null and undefined from T
type  E = NonNullable<string|number|null|undefined>;
let e:E = null;
Copy the code
10.7.3.4 ReturnType
  • Gets the return type of the function type`js function getUserInfo() { return { name: “zhufeng”, age: 10 }; }

// Assign the return value type of getUserInfo to UserInfo type UserInfo = ReturnType;

const userA: UserInfo = { name: “zhufeng”, age: 10 };

# # # # # 10.7.3.5 InstanceType < T >Js class Person{name:string; constructor(name){ this.name = name; }getName(){console.log(this.name)}
}

type  P = InstanceType<typeof Person>;
let p:P = {name:'zhufeng'.getName() {}};Copy the code

11. Type declaration

  • The declaration file allows us to use the system without having to refactor JS to TS and just add the declaration file
  • Type declarations are removed at compile time without affecting the actual code

11.1 Common Type Declaration

declareConst $:(selector:string)=>{// variable click():void; width(length:number):void; };declare letname:string; / / variabledeclare letage:number; / / variabledeclare functiongetName():string; / / methoddeclareClass Animal{name:string} // Class Person{name:string}typeStudent = {/ / declare the type name: string} |'string';
Copy the code

11.2 External Enumeration

  • External enumerations are useddeclare enumEnumeration type defined
  • External enumerations are used to describe the shape of an existing enumeration type
declare enum Seasons {
    Spring,
    Summer,
    Autumn,
    Winter
}

let seasons = [
    Seasons.Spring,
    Seasons.Summer,
    Seasons.Autumn,
    Seasons.Winter
];
Copy the code

Types defined by DECLARE are only used for compile-time checks and are removed from the compilation result. The compilation result of the previous example is as follows

var seasons = [
    Seasons.Spring,
    Seasons.Summer,
    Seasons.Autumn,
    Seasons.Winter
];
Copy the code

It is also possible to use both Declare and const

declare const enum Seasons {
    Spring,
    Summer,
    Autumn,
    Winter
}

let seasons = [
    Seasons.Spring,
    Seasons.Summer,
    Seasons.Autumn,
    Seasons.Winter
];
Copy the code

Compile the results

var seasons = [
    0 /* Spring */,
    1 /* Summer */,
    2 /* Autumn */,
    3 /* Winter */
];
Copy the code

11.3 the namespace

  • If a global variable contains many sub-attributes, you might use a namespace
  • In the declaration filenamespaceIndicates that a global variable contains many sub-attributes
  • There is no need to declare properties or methods inside the namespace using DECLARE
declare namespace ${
    function ajax(url:string,settings:any):void;
    let name:string;
    namespace fn {
        function extend(object:any):void;
    }
}
$.ajax('/api/users'{}); $.fn.extend({log:function(message:any){ console.log(message); }});export {};

Copy the code

11.4 Type declaration file

  • We can put the type declaration in a separate type declaration file
  • Type declarations can be used in a type declaration file
  • The file naming convention is*.d.ts
  • Looking at the type declaration file helps you understand how the library is used

11.4.1 jquery. Which s

typings\jquery.d.ts

declare const $:(selector:string)=>{
    click():void;
    width(length:number):void;
}
Copy the code

11.4.2 tsconfig. Json

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs"."target": "ES2015"."outDir":"lib"
  },
  "include": [
    "src/**/*"."typings/**/*"]}Copy the code

11.4.3 test. Js

$('#button').click();
$('#button').width(100);
export {};
Copy the code

11.5 Third-party Statement

  • You can install a declaration file that uses a third party
  • @types is a convention prefix that all third-party declared type libraries are prefixed with
  • JavaScript has many built-in objects that can be treated as declared types in TypeScript
  • Built-in objects are objects that exist in the Global scope according to the standard. Standards here are those of ECMAScript and other environments, such as DOM
  • The type declaration files for these built-in objects are included in the TypeScript core library type declaration files

11.5.1 using jquery

// For common.js style modules, you must use import * as import * as jQuery from'jquery';
jQuery.ajax('/user/1');
Copy the code

11.5.2 Installing the Declaration File

cnpm i @types/jquery -S
Copy the code

11.5.3 Write your own declaration files

types\jquery\index.d.ts

declare function jQuery(selector:string):HTMLElement;
declare namespace jQuery{
  function ajax(url:string):void
}
export default jQuery;
Copy the code

tsconfig.json

  • If it’s configuredpaths, so it will automatically go when the package is introducedpathsDirectory for the type declaration file
  • In WebPack, we can map files in a project by configuring aliases. intsconfig.jsonIn, we can also do the path mapping
  • In tsconfig.json, we passcompilerOptionsIn thepathsProperty to configure the pathmap. tsconfig.json
    {
    "baseUrl": ". /"// If you use the Paths attribute, you must specify the baseUrl value"paths": {
    "*": ["types/*"]}Copy the code

11.5.4 Possible location of the NPM declaration file

  • node_modules/jquery/package.json
    • “types”:”types/xxx.d.ts”
  • node_modules/jquery/index.d.ts
  • node_modules/@types/jquery/index.d.ts

11.6 Extending the type of a global variable

11.6.1 Extending local variable types

interface String {
    double():string;
}

String.prototype.double = function() {return this+'+'+this;
}
console.log('hello'.double());

interface Window{
    myname:string
}
console.log(window.myname);
//export {}
Copy the code

11.6.2 Global extension within a module

types\global\index.d.ts

declare global{
    interface String {
        double():string;
    }
    interface Window{
        myname:string
    }
}

export  {}
Copy the code
"include": [
    "src/**/*"."types/**/*"
]
Copy the code

11.7 Merging declarations

  • Two separate declarations of the same name are merged into a single declaration
  • The merged declaration has the characteristics of the original two declarations
  • A class can be used as either a type or a value, and an interface can only be used as a type
The keyword Use as a type Use as a value
class yes yes
enum yes yes
interface yes no
type yes no
function no yes
var,let,const no yes
class Person{
    name:string=' '
}
letp1:Person; // Use it as a typeletp2 = new Person(); Interface Animal{name:string}let a1:Animal;
leta2 = Animal; // Interface types cannot be used as valuesCopy the code

11.7.1 Merging type declarations

  • Features that can be merged through the interface are declared for extension types to a third party

use.js

interface Animal{
    name:string
}
let a1:Animal={name:'zhufeng',age:10};
console.log(a1.name);
console.log(a1.age);
Copy the code

types\animal\index.d.ts

interface Animal{
    age:number
}
Copy the code

11.7.2 Using namespaces to extend classes

  • We can extend a class using a namespace to represent an inner class
    class Form {
      username: Form.Item=' ';
      password: Form.Item=' '; } //Item is the inner class of Form namespace Form {export class Item {}
    }
    let item:Form.Item = new Form.Item();
    console.log(item);
    Copy the code

11.7.3 Using namespaces to extend functions

  • We can also usenamespaceTo extend the function
function greeting(name: string): string {
    return greeting.words+name;
}

namespace greeting {
    export let words = "Hello,";
}

console.log(greeting('zhufeng'))
Copy the code

11.7.4 Extending an enumeration type with a namespace

enum Color {
    red = 1,
    yellow = 2,
    blue = 3
}

namespace Color {
    export const green=4;
    export const purple=5;
}
console.log(Color.green)
Copy the code

11.8 Generate the declaration file #

  • The type declaration is lost when TS is compiled into JS. We can automatically generate a JS file at compile time
{
  "compilerOptions": {
     "declaration": true, /* Generates corresponding '.d.ts' file.*/
  }
}Copy the code