The installation

npm i typescript -g
Copy the code

Converted to js

  • Methods a
TSC File name. TsCopy the code
  • Method 2
    • vscode > terminal > run task > tsc:watch -tsconfig.json
    • vscode > terminal > run task > tsc:build -tsconfig.json
  • Methods three
    • Json: “build”: “TSC “, NPM run build

Generate the configuration file tsconfig.json

tsc --init
Copy the code

The data type

  • If export or import is present in a file,ts treats the file as a module, and the variables in the file become private and do not conflict with global variables
/ / a Boolean
let married: boolean = false;

/ / digital
let age: number = 0;

/ / string
let name: string = 'zhangsan'

// The array type is unique and the number is unstable
let arr1:number[] = [1.2.3]
let arr2: Array<number> = [7.8.9]

// A tuple, like an array, represents an array of known quantities and types
let school: [string.number] = ['zhangsan'.5]

// Common enumeration
enum Gender {
    MALE,
    FEMAL
}

// Not common enumeration constant enumeration
const enum Colors {
    Red,
    Yellow,
    Blue
}

// Any type
/** * any can be assigned to any type * - third-party libraries do not provide type declarations * - type conversions are difficult * - data structures are too complex */
 let root: HTMLElement | null = document.getElementById('root') root! .style.color ='red';  // A non-null assertion tells ts that I'm sure root cannot be null, so no error is reported
 let root: any = document.getElementById('root')
 root.style.color = 'red'
 
 // null undefined is a subtype of another type
 Json strictNullChecks = false can be assigned to other types
let x:number;
x = 1;
x = undefined;
x = null;

// void void means that no type is compatible with undefined
Json returns null if strictNullChecks = false
function greeting(name: string) :void {
    console.log(name);
}

// never a value that never occurs
// is a subtype of (null undefined)
function error(msg: string) :never {
    console.log(msg);
    throw new Error(msg);This function terminates abnormally and never returns a value
    console.log('over message')}let ret: never = error('hello')
// You can never reach the end of the line
functiion loop(): never {
    while(true) {}}function sum(x:number|string){
    if (typeof x === 'number') {
        console.log(x)
    } else if(typeof x === 'string') {
        console.log(x)
    } else {
        // It will never be possible to get here
        console.log(x)
    }
}

// never void distinction
// void can be assigned to null undefined, but never contains no value
// Functions that define a void return type work fine. Functions that return never never return
export {}
Copy the code

Enumerated type

Ordinary enumerations compile to ES5
enum Gender {
    MALE,
    FEMAL
}
console.log(Gender)
// Compile:
var Gender;
(function(Gender) {
    Gender[Gender['MALE'] = 0] = 'MALE';
    Gender[Gender['FEMALE'] = 1] = 'FEMALE';
})(Gender || (Gender = {}))
console.log(Gender) // {'0':'MALE', '1':'FEMALE', MALE:0, FEMALE:1}
Copy the code
Constant enumerations compile to ES5
const enum Colors {
    Red,
    Yellow,
    Blue
}
let myColors = [Colors.Red, Colors.Yellow, Colors.Blue]
// Compile:
var myColors = [0/*Red*/.1/*Yellow*/.2/*Blue*/]
Copy the code
Enumeration types are compatible with numeric types
enum Colors {
    Red,
    Yellow
}
let c: Colors
c = Colors.Red/ / 0
c = 0

let n: number
n = Colors.Yellow
Copy the code

Types of assertions

let name: string|number;/ / joint
(name as string).length;
(name as number).toFixed(2);
(<number>name).toFixed(2)
Copy the code

Literal type

  • Literals are unions of values, and unions are unions of types
  • Type is the TS keyword used to declare a new type
  • You can combine string/number/Boolean literals into a combined type
// Can only be these three values
type myType = 1|'one'|true;

let t1: myType = 1
let t2: myType = 'one'
let t3: myType = true
Copy the code

function

type UserFunction = (a: string, b: string) = > string
let getUserName: UserFunction = function(firstName: string, lastName: string) {
    return firstName + lastName;
}


// The optional argument must be the last
function print(name: string, age? :number) :void {
    console.log(name,age)
}

// Default parameters
function ajax(url: string, method: string = 'GET') {
    console.log(url,method)
}

// Remaining parameters
function sum(prefix: string. numbers:number[]) {
    return prefix + numbers.reduce((a,b) = > a+b)
}

// Function overload
Function implementation is missing or not immediately following the declaration.ts
let obj: any = {};
function attr(a:string,b:string);
function attr(a:number,b:number);
function attr(a:string|number,b:string|number){
    if (typeof val === 'string') {
        obj.name = val;
    } else if(typeof val === 'number') {
        obj.age = val;
    }
}
attr(1.1);// Correct call
attr('a'.'b');// Correct call
attr(1.'b');//No overload matches this call

// Function compatibility 1
// It is possible to pass fewer parameters
type functionType = (a: number, b: number) = > number
let sum: functionType;
function f1(a:number) :number {
    return a
}
sum = f1


// Function compatibility 2
// The function returns a value with more attributes, but not with fewer attributes
type GetPerson = () = > {name: string.age:number}
let getPerson: GetPerson;
function g1() {
    return {name:'zz'.age:10.home:'beijing'}
}
getPerson = g1

// Function compatibility 3
// More types can be fewer types can not
let sourceFunc = (a: number | string) = > {}
let targetFunc = (a: number | string | boolean) = > {}
Copy the code

Base type compatibility

let num: string | number;
let str: string = 'zll';
num = str

let num2:{
    toString(): string
}
let str2: string = 'jiagou'// The toString method returns string
num2 = str2
Copy the code

class

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

accessor

class User {
    myName: string = ' ';
    constructor(myName: string) {
        this.myName = myName;
    }
    get name() {return this.myName;
    }
    set name(value) {
        this.myName = value.toUpperCase(); }}let user = new User(' ');
user.name = 'zll'

Copy the code
// Public declarations can omit two lines of code
class User {
    // myName: string = '';
    constructor(public myName: string) {
        // this.myName = myName;
    }
    get name() {return this.myName;
    }
    set name(value) {
        this.myName = value.toUpperCase(); }}Copy the code
/ / readonly read-only
// Readonly is checked at compile time
// Const is checked at run time
class User {
    public readonly PI = 3.14;
    // myName: string = '';
    constructor(public myName: string) {
        // this.myName = myName;
    }
    get name() {return this.myName;
    }
    set name(value) {
        this.myName = value.toUpperCase(); }}Copy the code

public private protected

  • The public property means that the property can be used by the class itself. Subclasses and other classes
  • The protected property means that the property is accessible only to its own class and subclasses, but not to other classes
  • The private property means that the property can only be accessed by itself, not by subclasses or other classes
class Father {
    // public name: string;
    // protected age: number;
    // private money: number;
    constructor(public name: string.protected age:number.private money:number) {
        // this.name = name;
        // this.age = age;
        // this.money = money;
    }
    getMoney(){
        console.log(this.money)
    }
}
class Child extends Father {
    constructor(name: string,age:number,money:number) {
        super(name,age,money)
    }
    getName(){
        console.log(this.name)
    }
    getAge(){
        console.log(this.age)
    }
}
let child = new Child('zll'.10.100);
child.getName();
child.getAge();
child.getMoney();/ / no
child.name;
child.age;/ / no
child.money;/ / no
Copy the code

A decorator

  • A decorator is actually a function
Class decorator
// Attributes are merged for classes and interface definitions of the same name
//interface Person {
// name: string,
// eat:() => void
/ /}

// type Person = {name: string, eat: Function}; // The instance type
// target is the Person class type :typeof Person/Function/new () => Person
// If Person constructor has arguments to add :new (a: string) => Person
function enchancer(target:new () => Person) {
    target.prototype.name = 'zll';
    target.prototype.eat = function() {
        console.log(this.name)
    }
}

@enchancer
claass Person {

}
let p: any = new Person();// Use interface to resolve any
p.name;
p.eat()
Copy the code
Decoration Factory 1
function enhancer(name: string) {
    return function(target:new () => Person) {
        target.prototype.name = name;
        target.prototype.eat = function() {
            console.log(this.name)
        }
    }
}

@enhancer('zll')
class Person {}let p: any = new Person();
p.name;
p.eat()
Copy the code
Decoration Factory 2
// Replace the need for consistent class constructor arguments
function enchancer(target:new () => Person) {
    return class {
        constructor(public age:number){}name: string = 'zll';
        eat(){
            console.log(this.name)
        }
    }
}

@enchancer
claass Person {
    constructor(public age: number){}}let p = new Person(10);// Call name and eat without any type
p.name;
p.eat()
Copy the code
Attribute decorator
/** * The property decorator takes two arguments *@param Target is the constructor of the class if it is a static member, or the prototype object * if it is an instance member@param Property Specifies the name of the method or property */
function upperCase(target: any, property: string) {
    let value = target[property];
    const getter = () = > value;
    const setter = (newValue: string) = > {
        value = newValue.toUpperCase();
    } 
    if(delete target[property]) {
        Object.defineProperty(target,property,{
            get:getter,
            set: setter,
            enumerable: true.configurable:true}}})class Person {
    @upperCase
    name: string = 'zll';
}
let p = new Person
p.name = 'wang'
Copy the code
Method decorator
/ * * *@param Target is the constructor of the class if it is a static member, or the prototype object * if it is an instance member@param The name of the property method *@param Descriptor of the descriptor method */
function noEnumerable(target: any, property: string, descriptor: propertyDescriptor){
    descriptor.enumerable = false;
}
class Person {
    name: string = 'zll'
    @noEnumerable
    getName() {
        console.log(this.name)
    }
}
Copy the code
Parameter decorator
/ * * *@param Target is the constructor of the class if it is a static member, or the prototype object * if it is an instance member@param MethodName The name of the method *@param ParamsIndex Parameter index */
 interface Person {
     age: number
 }
function addAge(target: any, methodName: string, paramsIndex:number) {
    target.age = 10
}
class Person {
    login(username: string.@addAge password: string) {
        console.log(username, password)
    }
}
Copy the code

An abstract class

  • Abstract describes an abstract state that cannot be instantiated, but can only be inherited
  • Abstract methods cannot be implemented in abstract classes, only in concrete subclasses
  • Rewriting and overloading
    • Overloading refers to providing multiple type definitions, or function declarations, for a function
    • Overrides refer to methods that different subclasses implement in different ways
abstract class Animal {
    name: string;
    abstract speak(): void
}

/ / the cat
class Cat extends Animal {
    speak():void {
        console.log(Meow, meow, meow.)}}let cat =  new Cat();
cat.speak()

/ / the dog
class Dog extends Animal {
    speak():void {
        console.log(Woof woof woof)}}let dog =  new Dog();
dog.speak()
Copy the code

compatibility

class Animal {
    name: striing
}
class Bird extends Animal {
    swing: number
}
let a: Animal;
a = new Bird();
Copy the code

interface

Object shape

interface Speakable {
    name: string;
    speak(): void;
}
let person: Speakable = {
    name: 'zll'.speak(){}}Copy the code

Behavior abstraction

interface Speakable {
    speak(): void;
}
interface Eatable {
    eat(): void;
}
class Person implements Speakable.Eatable {
    speak() {
        console.log('speak')
    }
    eat(): void {
        console.log('eat')}}Copy the code

Any attribute

//interface Person {
// name: string,
// age: number,
// [key: string]: any // Any attribute
/ /}

// Record is the built-in type type Record
interface Person extends Record<string, any>{
    name: string.age: number
}
let p:Person={
    name: 'zll'.age: 10.home: 'beijing'.today: 1
}
Copy the code

Function interface type

// type Cost = (price: number) => number
interface Cost {
    (price: number) :number
}
let cost: Cost = function(price: number) :number {
    return price * 8
}
Copy the code

Indexable interface

interface UserInterface {
    [index: number] : string
}
let arr: UserInterface = ['1'.'2']
let obj:UserInterface = {
    0: 'a'.1: 'b'
}
Copy the code

The class implements the interface

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

Interface constraint class

class Animal {
    constructor(public name: string){}}interface WithNameClazz {
    new(name: string): Animal
}
function create(clazz: WithNameClazz,name: string) {
    return new clazz(name);
}
let a = create(Animal,'zll')
console.log(a)
Copy the code

Compatibility 1

  • If the variable passed does not match the declared type, TS does a compatibility check
  • Variables declared by the target type are compatible if they exist in the source type
interface Animal {
    name: string.age: number
}
interface Person {
    name: string.age: number.gender: number
}

function getName(animal: Animal) :string {
    return animal.name
}
let p: Person = {name:'zll'.age:10.gender:0}
getName(p)
Copy the code

Compatibility of 2

  • The parent interface can pass in parameters defined by the child interface
interface Event {
    timeStamp: number
}
interface MouseEvent extends Event {
    eventX: number.eventY: number
}
interface KeyEvent extends Event {
    keyCode: number
}
function addEventListener (eventType: string, handler:(event: MouseEvent) => void) {}
addEventListener('cliick'.(event: Event) = > {})
Copy the code

The problem

  • What is the difference between type and interface?
    • Type just defines a type alias interface is the real type
    • type a = string|number
    • type myType = 1|’one’|true;
    • type UserFunction = (a: string, b: string) => string
  • What’s the difference between class and interface?
    • An interface is just a type that modifies an object, or is implemented by a class, and then disappears after TS compilation
    • Classes are both types (types of instances of classes) and values (constructors)
  • What is the difference between an interface of a class and an abstract class?
    • The interface of a class is implemented by the class
    • Abstract classes are inherited

Generics (difficult)

  • When defining a function/interface/class, the specific type is not specified in advance, but is specified as it is used
function createArray<T> (length: number, value: T) :T[] {
    let result: T[] = [];
    for(let i = 0; i<length; i++) { result[i] = value; }return result;
}
let result = createArray<string> (3.'x');
console.log(result)
Copy the code

An array of class

function sum(. args:number[]) {
    for(let i = 0; i<args.length; i++) {console.log(args[i])
    }
}
sum(1.2.3)
Copy the code

A generic class

class MyArray<t> {
    private list: T[] = [];
    add(value:T) {
        this.list.push(value)
    }
}
let arr = new MyArray<number>()
arr.add(1)
Copy the code

A generic interface

interface Calculate {
    <T>(a:T,b:T):T
}
let add: Calculate = function<T> (a:T,b:T) {
    return a;
}
Copy the code
interface Calculate<A> {
    <B>(a:A,b:B):A
}
let add: Calculate<number> = function<B> (a:number,b:B) {
    return a;
}
add<string> (1.'b')
Copy the code

The default generic

interface Calculate<A = number> {
    <B>(a:A,b:B):A
}
let add: Calculate = function<B> (a:number,b:B) {
    return a;
}
add<string> (1.'b')
Copy the code

Interface generic constraints

  • By default, you can’t call any properties or methods on a generic because you don’t know what value will be passed in at definition
interface LengthWise {
    length: number
}
function logger<T extends LengthWise> (val:T) {
    console.log(val.length)
}
logger<string> ('d')
Copy the code

Generic type alias

type Cart<T> = {list:T[]} | T[]
let c1: Cart<string> = {list: ['1']}
let c2: Cart<number> = [1.2.3]
Copy the code

Generic compatibility

interface Empty<T> {}
letx! : Empty<string>;
lety! : Empty<number>;
x = y/ / can

interface Empty1<T> {
    data: T
}
letx1! : Empty1<string>;
lety1! : Empty1<number>;
x1 = y1;/ / an error
Copy the code