A, install,

Global installation

npm install typescript -g
Copy the code

Check the version

tsc --version
Copy the code

2. Operating environment

Method 1: Configure the environment with Webpack

npm init -y
Copy the code

Install dependencies

npm i webpack webpack-cli typescript webpack-dev-server ts-loader html-webpack-plugin
Copy the code

Package. The json configuration

"scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "webpack",
    "serve": "webpack serve"
  },
Copy the code

Create a tsconfig.json configuration file

tsc --init
Copy the code

Configuration related to webpack.config.js

const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
​
module.exports = {
  mode: 'development',
  entry: './src/main.ts',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js'
  },
  resolve: {
    extensions: ['.js', '.cjs', '.ts', '.json']
  },
  module: {
    rules: [
      {
        test: /.ts$/,
        loader: 'ts-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: './index.html'
    })
  ]
};
Copy the code

Create an index. HTML on the root path

Finally by starting the project

npm run serve
Copy the code

Method 2: TS-Node

Install TS-Node. Ts-node depends on the tSLIb and @types/node packages

npm install ts-node tslib @types/node -g
Copy the code

Running the TS file

ts-node math.ts
Copy the code

3. Declaration of variables

1. Definition of variables

Var /let/const identifier: data type = assignmentCopy the code

2. Use of the number type

let num1: number = 12345
let num2: number = 0b101
let num3: number = 0o567
let num4: number = 0x45def
​
console.log(num1, num2, num3, num4)
export {}
Copy the code

3. Use the Boolean type

let flag: boolean = true
flag = 20 > 30
​
console.log(flag) // false
export {}
Copy the code

4. Use of the string type

Let message: string = 'hello world' let message: string = 'hello world' export {}Copy the code

5. Use of the array type

Const arr: Array<string> = [] const arr: Array<string> = [] const arr: Array<string> = [] String [] = [] / / recommend arr. Push (' ABC ') arr. Push (' BBC ') arr. Push (123) / / an error export {}Copy the code

6. Use of the object type

const obj = {
  name: 'yogln',
  age: 18
}
​
console.log(obj.name)
Copy the code

7. Null and un______ type

let n: null = null
let u: undefined = undefined
Copy the code

8. Use of the symbol type

Let s1 = Symbol('title') const obj = {[s1]: 'front ', [s2]:' development '} export {} let s2 = Symbol('title') const obj = {[s1]: 'front ', [s2]:' development '}Copy the code

TypeScript data types

1. Use the any type

// When making some type assertions as any // when you don't want to add specific data types to some JavaScript (native JavaScript code is the same) let message: any = 'Hello World' message = 123 message = true message = {}Copy the code

2. Use of the unknown type

Function foo(arg:) function foo(arg:) unknown) { console.log(typeof arg) } foo('123') foo(123)Copy the code

Use of the void type

function sum(num1: number, num2: number): void {
  console.log(num1 + num2)
}
​
sum(20, 30)
Copy the code

Void may not be written

4. Use of the never type

function handleMessage(message: number | string | boolean) { switch (typeof message) { case 'number': Console. log('number handler ') break case 'string': console.log('strign handler ') break case 'Boolean ': Console. log(' Boolean handler ') break default: const check: Never = message}} handleMessage(' ABC ') handleMessage(123)Copy the code

5. Use of the tuple type

// tuple const info: [string, number, string] = ['yogln', 18, 'front '] const name = info[0] console.log(name) export {}Copy the code

6. Tuple Application scenario of the tuple

// hook: useState
// const [counter, setCounter] = {counter: , setCounter:}
​
function useState(state: any) {
  let currentState = state
  const changeState = (newState: any) => {
    currentState = newState
  }
  const tuple: [any, (newState: any) => void] = [currentState, changeState]
  return tuple
}
const [counter, setCounter] = useState(10)
​
export {}
Copy the code

Of course, we can also optimize to use generics

// hook: useState
// const [counter, setCounter] = {counter: , setCounter:}
​
function useState<T>(state: T) {
  let currentState = state
  const changeState = (newState: T) => {
    currentState = newState
  }
  const tuple: [T, (newState: T) => void] = [currentState, changeState]
  return tuple
}
const [counter, setCounter] = useState(10)
​
export {}
​
Copy the code

5. Other types of supplements

1. The types of parameters and return values of the function

Num1: number; num2: number; num1: number; num2: number; num1: number; num1: number; number, num2: number) { return num1 + num2 } // sum(123, 321)Copy the code

So you don’t usually write the type of the return value

Anonymous functions can be pushed to get the type of the parameter and the type of the return value

Const names = [" ABC ", "cba", "NBA "] const names = [" ABC ", "cba"," NBA "] Names.foreach (function(item) {console.log(item.split(""))})Copy the code

2. Object type

function printPoint(point: { x: number; y: number }) {
  console.log(point.x, point.y)
}
​
printPoint({ x: 2, y: 4 })
Copy the code

3. Is the type optional?

z? : number

function printPoint(point: { x: number; y: number; z? : number }) { console.log(point.x) console.log(point.y) console.log(point.z) } printPoint({ x: 123, y: 321 }) printPoint({ x: 123, y: 321, z: 111 }) export {}Copy the code

4. | joint type

function print(id: number | string) {
  console.log(id)
}
print(123)
print('abc')
​
export {}
Copy the code

5. The type alias is type

type PointType = { x: number y: number z? : number } function printPoint(point: PointType) { console.log(point.x, point.y, point.z) } printPoint({ x: 2, y: 2 })Copy the code

6. Type assertion as

As // <img id="why"/> const el = document.getelementById ('yogln') as HTMLImageElement el.src = 'image URL' // 2. Class Person {} class Student extends Person {studying() {}} function sayHello(p: Person) {; (p as Student).studying() } const stu = new Student() sayHello(stu) // 3. as any/unknown let message = 'hello world' const num: number = message as any as numberCopy the code

7. Non-empty type assertions! .

Prints the length of the optional type

function printMsgLength(msg? : string) { console.log(msg! .length) } printMsgLength('hello world')Copy the code

8. Use of optional chains? .

type Person = { name: string age: number friend: { name: string girlfriend? : { name: string } } } const info: Person = { name: 'yogln', age: 18, friend: { name: 'why' } } console.log(info.friend?.name) // why console.log(info.friend?.girlfriend?.name) //undefined export {}Copy the code

9.!!!!! The operator

const message = 'Hello World' console.log(! message) //false console.log(!! message) //trueCopy the code

10.?? The operator

let message: string | null = 'Hello World' const content = message ?? // const content = message? Message: "Hello, Li Yinhe" console.log(content) // Hello, Li YinheCopy the code

Let num: 123 = 123

const msg: 'hello world' = 'hello world' let num: 123 = 123 / / num literal type of value must be the same and literal / / num = 234 / / an error type Alignment = 'left' | 'right' | 'center' let Alignment: Alignment = 'left' alignment = 'center'Copy the code

12. Literal reasoning

type Method = 'GET' | 'POST'
​
function request(url: string, method: Method) {}
​
const options = {
  url: 'https://www.yogln.com',
  method: 'POST'
} as const
request(options.url, options.method)
​
export {}
Copy the code

13. Type reduction

  • Typeof is reduced

    / / 1. The type of the typeof narrow type IdType = string | number function named printType (id: IdType) { if (typeof id === 'string') { console.log(id.toUpperCase()) } else { console.log(id) } }Copy the code
  • Narrowing of equality types

    / / 2. Equal type narrow type Direction = 'left' | 'right' function pintDirection (Direction: If (Direction === 'left') {// console.log(Direction) // else if () // 2.switch judgment // switch (direction) { // case 'left': // console.log(direction) // break; // case ... / /}}Copy the code
  • instanceof

    // 3. instanceof
    function printTime(time: string | Date) {
      if (time instanceof Date) {
        console.log(time.toUTCString())
      } else {
        console.log(time)
      }
    }
    ​
    class Student {
      studying() {}
    }
    ​
    class Teacher {
      teaching() {}
    }
    ​
    function work(p: Student | Teacher) {
      if (p instanceof Student) {
        p.studying()
      } else {
        p.teaching()
      }
    }
    ​
    const stu = new Student()
    work(stu)
    Copy the code
  • in

    // 4. in
    type Fish = {
      swimming: () => void
    }
    ​
    type Dog = {
      running: () => void
    }
    ​
    function walk(animal: Fish | Dog) {
      if ('swimming' in animal) {
        animal.swimming()
      } else {
        animal.running()
      }
    }
    const fish: Fish = {
      swimming() {
        console.log('swimming')
      }
    }
    walk(fish)
    Copy the code

TypeScript functions

1. Type of the function

  • The type of function written when defining a constant
type AddType = (num1: number, num2: number) => number
const add: AddType = (num1: number, num2: number) => {
  return num1 + num2
}
Copy the code
  • Function as an argument to a function
Function foo() {} type foo = () => void function foo(fn: FnType) {fn()} foo()Copy the code

2. Examples of function types

function calc(n1: number, n2: number, fn: (n1: number, n2: number) => number) {
  return fn(n1, n2)
}
​
const res1 = calc(20, 30, function (n1, n2) {
  return n1 + n2
})
console.log(res1) //50
const res2 = calc(20, 30, function (n1, n2) {
  return n1 * n2
})
console.log(res2) //600
Copy the code

3. Optional types of functions

The optional type of the function must be written after the required type

// y -> undefined | number function foo(x: number, y? : number) { } foo(20, 30) foo(20)Copy the code

4. Default values for function parameters

function foo(num1: number, num2: number = 20) {
  console.log(num1, num2)
}
foo(20) // 20, 20
Copy the code

5. Remaining parameters of the function

function total(initial: number, ... nums: number[]): number { let res = initial for (const num of nums) { res += num } return res } console.log(total(20, 30)) //50 console.log(total(20, 30, 40)) //90Copy the code

6. Default derivation of this

const obj = {
  name: 'yogln',
  eating() {
    console.log(this.name + ' eating')
  }
}
obj.eating() //yogln eating
Copy the code

7. This binding

type ThisType = { name: string } function eating(this: ThisType, msg: string) { console.log(this.name, msg) } const info = { name: 'yogln', eating: // yogln hahaha // yogln hahaha // info.eating. Call ({name: 'explicit binding'}, 'explicit binding ')Copy the code

Notice the difference between call and apply

Apply passes the arguments that need to be passed to fn in an array (or an array of classes). It is written as an array, but it is passed to FN one by one

fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);
Copy the code

The bind syntax is the same as the call syntax. The difference is whether bind executes immediately or waits

fn.call(obj, 1, 2); Bind (obj, 1, 2); bind(obj, 1, 2); // Change this in fn, fn does not executeCopy the code

8. Function overloading

function add(num1: number, num2: number): number
function add(num1: string, num2: string): string
​
function add(num1: any, num2: any): any {
  if (typeof num1 === 'string' && typeof num2 === 'string') {
    return num1.length + num2.length
  }
  return num1 + num2
}
​
console.log(add(123, 321))
console.log(add('yogln', 'ts'))
export {}
Copy the code

Definitions of TypeScript classes

1. Class definition

class Person {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  eating() {
    console.log(this.name + ' eating')
  }
}
​
const p = new Person('yogln', 18)
console.log(p)
p.eating()
Copy the code

2. Class inheritance

class Person { name: string age: number constructor(name: string, age: number) { this.name = name this.age = age } eating() {} } class Student extends Person { status: string constructor(name: string, age: number, status: string) { super(name, Age) this.status = status} // overwrite the parent class method eating() {console.log(this.name + 'eating')}} const s = new Student('yogln', 18, 'student') console.log(s) s.eating()Copy the code

3. Polymorphism of classes

class Animal {
  moving() {
    console.log('animal moving')
  }
}
​
class Dog extends Animal {
  moving() {
    console.log('dog running')
  }
}
​
class Bird extends Animal {
  moving() {
    console.log('bird flying')
  }
}
​
function makeMove(animals: Animal[]) {
  animals.forEach((animal) => {
    animal.moving()
  })
}
makeMove([new Dog(), new Bird()])
// dog running
// bird flying
Copy the code

4. Member attribute private

Private member properties, created instances and external can not be directly called and modified, can call the methods inside to get and call

class Person { private name: string = '' setName(name: String) {this.name = name} getName() {return this.name}} const p = new Person() // console.log(p.name)// console.log(p.getName()) // p.setName('yogln') console.log(p.getName()) // yoglnCopy the code

5. Member property protected

A protected member cannot be called directly outside its property, but its subclass inheritance can

class Person {
  protected name: string = 'yogln'
}
​
class Student extends Person {
  getName() {
    return this.name
  }
}
​
const stu = new Student()
console.log(stu.getName()) // yogln
Copy the code

6. Read-only attribute readonly

  1. Read-only attributes can be assigned in the constructor
  2. The property itself cannot be modified, but if it is an object type, the property value in the object can be modified
class Person { readonly name: string age? : number readonly friend? : Person constructor(name: string, friend? : Person) {this.name = name this.friend = friend}} const p1 = new Person('yogln') // p1.name = 'why' const p2 =  new Person('yogln', new Person('Jhon')) if (p2.friend) { p2.friend.age = 20 } console.log(p2.friend)Copy the code

7. The setter and getter

Private members of a class are not accessible, so we can use sertter and getters

class Person {
  private _name: string
​
  constructor(_name: string) {
    this._name = _name
  }
​
  set name(newName) {
    this._name = newName
  }
​
  get name() {
    return this._name
  }
}
​
const p = new Person('yogln')
p.name = 'kobe'
console.log(p.name)
Copy the code

8. Class static member property static

You can directly call properties and methods in a class without creating an instance

class Student {
  static stuName: string = 'yogln'
​
  static studying() {
    console.log(this.stuName + ' studying')
  }
}
​
console.log(Student.stuName) //yogln
Student.studying() // yogln studying
Copy the code

9. Abstract class Acstracts

Class names and methods in abstract classes need to be modified by abstractions

abstract class Shape { abstract getArea(): number } class Rectangle extends Shape { private x: number private y: number constructor(x: number, y: number) { super() this.x = x this.y = y } getArea() { return this.x * this.y } } class Circle extends Shape { private radius: number constructor(radius: Number) {super() this.radius = radius} getArea() {return this.radius * this.radius * 3.14}} const circle = new Circle(2) Console.log (Circle. GetArea ()) //12.56 const Rectangle = new Rectangle(2, 3) console.log(rectangle.getArea())// 6Copy the code

Use of interfaces

1. Declare the object type

interface InfoType { readonly name: string age: number friend? : { name: string } } const info: InfoType = { name: 'yogln', age: 18 } console.log(info)//{ name: 'yogln', age: 18 }Copy the code

2. Define the index type of the object

Interface IndexLanguage {[index: number]: string} const frontLange: IndexLanguage = {[0]: 'vue, [1] :' the react / / [a] : the correct 'HTML' / / / / b: / / an error} 'CSS'Copy the code

3. Interface inheritance

interface ISwim {
  swimming: () => void
}
interface IFly {
  flying: () => void
}
​
interface IAction extends ISwim, IFly {}
const action: IAction = {
  swimming() {},
​
  flying() {}
}
Copy the code

4. Crossover types

When you declare a type

// Another way of component type: cross type type NeverType = number & string // This is actually impossible, so NeverType returns the type neverCopy the code

Types in interfaces

interface Swim {
  swimming: () => void
}
interface Fly {
  flying: () => void
}
type MyType1 = Swim | Fly
type MyType2 = Swim & Fly
const obj1: MyType1 = {
  flying() {}
}
const obj2: MyType2 = {
  flying() {},
  swimming() {}
}
Copy the code

When an object has two return types, all methods must be implemented

5. Interface implementation

Interfaces, once defined, can also be implemented by classes:

If implemented by a class, you can pass that class in wherever you later need to pass an interface, which is interface-oriented development.

interface ISwim {
  swimming: () = > void
}
interface IFly {
  flying: () = > void
}

class Person implements ISwim.IFly {
  swimming() {}
  flying(){}}function swim(swim: ISwim) {
  swim.swimming()
}

const p = new Person()
swim(p)
Copy the code

6. The difference between interface and type

In general, it is recommended to use type for non-object types, but object types such as type and interface are acceptable, so how do we use them?

interface IFoo {
  name: string
}

interface IFoo {
  age: 18
}

const foo: IFoo = {
  name: 'yogln'.age: 18
}
Copy the code

You can see that interface can repeat attributes and methods, and the attributes defined are merged together, but type cannot, and the alias of type cannot be repeated, so that’s the difference

7. Literal assignment

interface IPerson {
	name: string;
	age: number;
}

const info: IPerson = {
	name: 'yogln'.age: 18.address: 'zh' // Direct error
}
Copy the code

We find that the info object has one more address than the interface definition, and we get an error if we assign the value as follows

interface IPerson {
  name: string
  age: number
}
const obj = {
  name: 'yogln'.age: 18.address: 'zh' // No error will be reported
}

const info: IPerson = obj
console.log(info) // { name: 'yogln', age: 18, address: 'zh' }
Copy the code

Why is that?

This is because TypeScript imposes strict type restrictions for type inference during direct assignments to literals. But later it will do freshness if we assign one variable identifier to other variables.

8. Enumeration types

enum Direction {
  LEFT,
  RIGHT,
  TOP,
  BOTTOM
}

function trunDirection(direction: Direction) {
  switch (direction) {
    case Direction.LEFT:
      console.log('turn left')
      break
    case Direction.RIGHT:
      console.log('right')
      break
    case Direction.TOP:
      console.log('向上')
      break
    case Direction.BOTTOM:
      console.log('down')
      break
    default:
      const foo: never = direction
      break}}Copy the code

9. Enumeration type values

Enumeration types have default values

enum Direction {
  LEFT, / / 0
  RIGHT, / / 1
  TOP, / / 2
  BOTTOM / / 3
}
Copy the code

We can also assign other types of values to them

enum Direction {
  LEFT = "LEFT",
  RIGHT = "RIGHT",
  TOP = "TOP",
  BOTTOM = "BOTTOM"
}
Copy the code

So can we

let d: Direction = Direction.LEFT
Copy the code

Recognize generics

1. How generics are defined

function sum<T> (arg: T) {
  return arg
}

sum<number> (1)
sum<string> ('abc')
sum<any[] > ['abc'])
Copy the code

2. Generic parameter types

There are some common names that you might see in development:

  • T: Short for Type, Type
  • K, V: short for key and value, key-value pairs
  • E: Short for Element
  • O:ObjectThe abbreviation, object
function foo<T.E.O> (arg1: T, arg2: E, arg3: O) {}

foo<number.string.boolean> (10.'yogln'.true)
Copy the code

3. Use of generic interfaces

interface IPerson<T1 = string, T2 = number> {
  name: T1
  age: T2
}

const p: IPerson = {
  name: 'yogln'.age: 18
}
Copy the code

4. Use of generic classes

class Person<T1.T2> {
  x: T1
  y: T2

  constructor(x, y) {
    this.x = x
    this.y = y
  }
}

const p: Person<string.number> = new Person('yogln'.18)
Copy the code

5. Type constraints for generics

You want to print a length with length

interface ILength {
  length: number
}

function printLength<T extends ILength> (arg: T) {
  return arg.length
}

printLength('abcd')
printLength(['a'.'b'.'c'])
printLength({ length: 100 })
Copy the code

X. Modularity

1. Modular development

TypeScript supports our scope in two ways

  • Modularity: Each file is a separate module
  • Namespace: A namespace is declared by the namespace

When we export two functions with the same name, an error is generated

export function format() {
  return 'timeFormat'
}

export function format() {
  return 'priceFormat'
}
Copy the code

We can change the name of the function differently, and we can also use namespace

export namespace time {
  export function format() {
    return 'timeFormat'}}export namespace price {
  export function format() {
    return 'priceFormat'}}Copy the code

When you import it

import { time } from './utils/format'

console.log(time.format())
Copy the code

2. Search for the type

When we use it in TS

const imgEl = document.getElementById('image') as HTMLImageElement
Copy the code

Are you wondering where our HTMLImageElement type comes from? Why can document even have a method for getElementById? Here comes typescript’s rules for managing types and finding them

There’s another type of typescript file that we’ll start with:.d.ts files, which are used to declare types. It’s only used for type checking to tell typescript what types we have

So where does typescript look for our type declarations?

  1. Built-in type declaration;
  2. External definition type declaration;
  3. Define your own type declaration

Built-in type declaration

Built-in type declarations are declarations that come with typescript and help us build in some of the standardized apis of the JavaScript runtime. This includes built-in types such as Math and Date as well as DOM apis such as Window and Document. Built-in type declarations are usually included in the context in which we install typescript

Github.com/microsoft/T…

Externally defined type declarations

External type declarations are usually required when we use libraries such as third-party libraries. These libraries usually have two types of type declarations:

  • Method one: Make type declarations in your own library (write. D. ts files), such as Axios

  • Method 2: Store type declarations through DefinitelyTyped public library in the community

    The library is GitHub: github.com/DefinitelyT…

    The library search statement installation address: www.typescriptlang.org/dt/search?s…

    For example, we install the react type declaration: npmi@types /react –save-dev

For example, if we have lodash installed and we want to use it, we can search the site for installation-related dependencies

Define your own type declaration

When do you need to define your own declaration file?

  • Case 1: We use a third-party library is a pure JavaScript library, there is no corresponding declaration file; Such as lodash
  • In case two, we declare some types in our code so that we can use them directly elsewhere.

For example, we define the name and age in the index. HTML file, which we want to use in main.ts

<script>
  let name = 'yogln'
  let age = '18'
</script>
Copy the code
console.log(name)
console.log(age)
Copy the code

We can’t just use it, we need to create a.d.ts file with whatever name and location we want to use to declare the variables we want to use

declare let name: string
declare let age: number
Copy the code

That’s good at this point

The same goes for declaring functions and declaring classes

declare function foo(): void
​
declare class Person {
  name: string
  age: number
​
  constructor(name: string, age: number)
}
Copy the code

Declare the module lodash

declare module 'loadsh' {
  export function join(args: any[]): any
}
Copy the code