Website recommendation
Type basis
Strong type and weak type
- Strongly typed language: it is not allowed to change the data type of a variable unless it is cast
- Weakly typed language: variables can be assigned different data types
Static type and dynamic type
- Statically typed language: determines the type of all variables at compile time
- Dynamically typed language: determines the type of all variables at the execution stage
initialization
npm i typescript -g # initialization npm init -y tsc --init
{ "clean-webpack-plugin": "^3.0.0", "html-webpack-plugin": "^3.2.0", "ts-loader": "^8.1.0", "typescript": "^4.2.4", "webpack": "^4.32.2", "webpack-cli": "^3.3.2", "webpack-dev-server": "^3.5.1", "webpack-merge": "^4.2.1" }
Environment configuration webpack base. config. js
npm i webpack webpack-cli webpack-dev-server -D npm i ts-loader typescript -D npm i html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: { app: './src/index.ts', }, output: { filename: 'app.js', }, resolve: { extensions: ['.js', '.tsx', '.ts'], }, module: { rules: [ { test: /\.tsx?$/i, use: [ { loader: 'ts-loader', }, ], exclude: /node_modules/, }, ], }, plugins: [ new HtmlWebpackPlugin({ template: './src/tpl/index.html', }), ], }
Environment configuration webpack dev.config. js
- Soap ignores the chain information of the source map
- module locate ts source code
- Eval source map packages the source map into a file as a url
module.exports = { // devtool: 'cheap-module-eval-source-map', }
Environment configuration webpack pro. config. js
npm i clean-webpack-plugin -D
const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { plugins: [new CleanWebpackPlugin()], }
Environment configuration webpack config. js
npm i webpack-merge -D # Merge two webpack configuration items
const merge = require('webpack-merge') const baseConfig = require('./webpack.base.config') const devConfig = require('./webpack.dev.config') const proConfig = require('./webpack.pro.config') let config = process.NODE_ENV === 'development' ? devConfig : proConfig module.exports = merge(baseConfig, config)
hello world
let hello: string = 'hello world' document.querySelectorAll('.app')[0].innerHTML = hello
Basic type
ES6 data type
- Boolean
- Number
- String
- Array
- Function
- Object
- Symbol
- undefined
- null
TypeScript data type
Added on the basis of ES6 data type
- void
- any
- never
- tuple
- enumeration
- Advanced type
type annotation
- Equivalent to a type declaration in a strongly typed language
- Syntax: (variable / function): type
// Original type let bool: boolean = true let num: number = 123 let str: string = 'abc' // array let arr1: number[] = [1, 2, 3] let arr2: Array<number | string> = [1, 2, 3, '4'] // tuple let tuple: [number, string] = [0, '1'] // function let add = (x: number, y: number): number => x + y let compute: (x: number, y: number) => number compute = (a, b) => a + b // object let obj: { x: number; y: number } = { x: 1, y: 2 } // symbol let s1: symbol = Symbol() // void let noReturn = () => {} // any can modify it at will let x x = 1 x = []
undefined and null
- Is a subtype of all types, that is, you can assign undefined and null to variables of type number
let un: undefined = undefined let nu: null = null /* terms of settlement 1.tsconfig Modify "strictnullchecks" in: false 2.Use union type let num: number | undefined | null = 123 */ num = undefined // report errors
never
- A function throws an exception
- A function never returns a result
// never let error = () => { throw new Error('error') } let endless = () => { while (true) {} }
Enumeration type
Enumeration: a set of constants with names (which can be understood as address book)
- Enum is defined using enum keyword
// Numeric enumeration (reverse mapping) enum Role { Reporter = 1, Developer, Maintainer, Owner, Guest, } // String Enum enum Message { Success = 'success', Fail = 'fail', } // Heterogeneous enumeration enum Answer { N, Y = 'Yes', } // Constant enumeration (which will be removed at compile time) works: you don't need an object, you need the value of an object const enum Month { Jan, Feb, Mar, } let month = [Month.Jan, Month.Feb, Month.Mar]
Enumerating members
-
Constant enumeration
- Without initial value
- Reference to an existing enumeration member
- Constant expression
-
Compute enumeration
The calculation is not performed during the compilation phase, but remains until the execution phase of the program
// Enumerating members enum Char { // constant members a, b = Char.a, c = 1 + 3, // computed member d = Math.random(), e = '123'.length, }
Enumeration type
// Enumeration type (in some cases, enumeration and enumeration members can exist as a single type) enum E { a, b, } // Enumeration members do not have any initial values enum F { a = 0, b = 1, } // All members are numeric enumerations enum G { a = 'apple', b = 'banana', } // Comparisons cannot be made between different enumeration types let e: E = 3 let f: F = 3 let e1: E.a = 1 let e2: E.b let e3: E.a = 1 let g1: G = G.a let g2: G.a
Interface
Object type interface
One of the core principles of ts is to type check the structure of values, which is sometimes called "duck type identification method". In ts, the function of interfaces is to name these types and define contracts with your code or third-party code
- If the incoming interface meets the necessary conditions, it is allowed. Even if the incoming redundant fields can pass the type check
- Exception: if an object literal is passed in directly, the ts will check for additional fields
- Pass the object literal to a variable
- Use type assertion as result < result >
- Use string index signature [x: string]: any
The variable uses const and the attribute uses readonly
interface List { readonly id: number // read-only name: string [x: string]: any age?: number // ? not essential } interface Result { data: List[] } function render(result: Result) { result.data.forEach(value => { console.log(value.id, value.name) if (value.age) { console.log(value.age) } }) } let result = { data: [ { id: 1, name: 'A', sex: 'male' }, { id: 2, name: 'B' }, ], } render((<Result>{ data: [ { id: 1, name: 'A', sex: 'male' }, { id: 2, name: 'B' }, ], }) as Result)
You can use indexable types when you are not sure how many properties there are in an interface
- String and numeric index
- Two types of indexes can be used at the same time, but the return value of a numeric index must be a subtype of the return value type of a string index (indexing with 100 is equivalent to indexing with "100")
// Digital index interface StringArray { [index: number]: string } let chars: StringArray = ['A', 'B'] // String index interface Names { [x: string]: string [z: number]: string }
Function type interface
The following two definitions are equivalent
// Variable declaration let add: (x: number, y: number) => number // Interface declaration interface Add { (x: number, y: number): number }
Type alias
// Use type alias type Add = (x: number, y: number) => number let add: Add = (a, b) => a + b
Hybrid interface
interface Lib { (): void version: string doSomething(): void } function getLib() { let lib: Lib = (() => {}) as Lib lib.version = '1.0' lib.doSomething = () => {} return lib } let lib1 = getLib() lib1() lib1.doSomething()
Summary of function related knowledge points
Four ways of function definition
- The latter three are just the definition of function types, but have no specific implementation
function add1(x: number, y: number) { return x + y } let add2: (x: number, y: number) => number type add3 = (x: number, y: number) => number interface add4 { (x: number, y: number): number }
// Optional parameters must precede the required parameters function add5(x: number, y?: number) { return y ? x + y : x } // Function overload (two functions have the same name and different number / type of parameters) function add6(...rest: number[]): number function add6(...rest: string[]): string function add6(...rest: any[]): any { let first = rest[0] if (typeof first === 'string') { return rest.join('') } if (typeof first === 'number') { return rest.reduce((pre, cur) => pre + cur) } } console.log(add6(1, 2, 3)) // 6 console.log(add6('a', 'b', 'c')) // abc
class
Inheritance and member modifiers
- All properties are public by default
- The private member private can only be called in the class itself, not by the instance of the class or by the subclass
- protected is similar to private, but it can be called in subclasses
- readonly sets the property to read-only
class Dog { // If you add private to the constructor: it can neither be instantiated nor inherited constructor(name: string) { this.name = name } name: string run() {} private pri() {} protected pro() {} readonly legs: number = 4 } console.log(Dog.prototype) let dog = new Dog('wang') console.log(dog) // dog.pri() // dog.pro() class Husky extends Dog { constructor(name: string, public color: string) { super(name) this.color = color // this.pri() this.pro() } // color: string }
Abstract classes and polymorphism
- Cannot inherit an instance of an abstract class
Benefits of abstract classes:
- It can isolate the commonness of some things, which is conducive to code reuse and expansion
- Abstract classes can realize polymorphism (define a method in the parent class, have different implementations of this method in multiple subclasses, and perform different operations on different objects during program running, so as to realize runtime binding)
abstract class Animal { eat() { console.log('eat') } abstract sleep(): void // Abstract method } // let animal = new Animal() class Dog extends Animal { constructor(name: string) { super() this.name = name } name: string run() {} sleep() { console.log('dog sleep') } } let dog = new Dog('wang') dog.eat() class Cat extends Animal { sleep() { console.log('cat sleep') } } let cat = new Cat() let animals: Animal[] = [dog, cat] animals.forEach(i => { i.sleep() })
Polymorphism in inheritance
class WorkFlow { step1() { return this } step2() { return this } } new WorkFlow().step1().step2() // Polymorphism in inheritance: this can be either a parent type or a child type class MyFlow extends WorkFlow { next() { return this } } new MyFlow().next().step1().next().step2()
Relationship between class and interface
be careful:
- Class must declare all properties of the interface when it implements the interface
- An interface can only constrain public members of a class
- An interface cannot constrain the constructor of a class
interface Human { // new (name: string): void name: string eat(): void } class Asian implements Human { constructor(name: string) { this.name = name } // private name: string name: string eat() {} sleep() {} }
Differences between implements and extensions
- implements treats the class as an interface, which means that you must implement all the methods defined in the class, whether they have a default implementation in the class or not, and there is no need to use super()
- Extensions requires super()
interface Human { name: string eat(): void } interface Man extends Human { run(): void } interface Child { cry(): void } interface Boy extends Man, Child {} let boy: Boy = { name: '', run() {}, eat() {}, cry() {}, }
In addition to inheriting the interface, the interface can also inherit the class, which is equivalent to that the interface abstracts the members of the class (only the member structure of the class without specific implementation)
class Auto { state = 1 } // state is implicit in the interface interface AutoInterface extends Auto {} // Subclasses of Auto can also implement the interface of AutoInterface. C is not a subclass of Auto and does not contain non-public members of Auto class C implements AutoInterface { state = 1 } // It is a subclass of Auto and inherits state. When the interface pulls out the members of the class, it pulls out not only the public members, but also the protected members and private members class Bus extends Auto implements AutoInterface {}
Relationship:
- Interfaces (reuse between interfaces) and classes (reuse between methods and attributes) can inherit from each other
- Interfaces can be implemented through classes, but interfaces can only restrict the public members of classes
- Interfaces can also pull out members of classes, including public members, private members and protected members