Typescript basis

What is Typescript?

There are two types of programming languages:

  • Dynamically typed languages: The type of a variable can only be determined at run time (e.gJS / Python)
  • Statically typed languages: Variable types are determined at compile time, and errors can be detected (e.gc++ / c / c# / java)

TS features:

  • Javascript that scales (superset of JS)
  • Statically typed style type system
  • fromes6toes10evenesnextSyntax support for
  • Compatible with all browsers, all kinds of systems, all kinds of servers, completely open source

2. Why use TS?

  • The program is easier to understand: it is easy to know the input and output types of functions and external conditions, and the probability of error is small
  • Most errors can be found during compilation
  • Fully compatible with JS

3. Basic use

Create the test.ts file

const hello = (name:string) = > {
  return `Hello ${name}`
}

hello('Axton Tang')
Copy the code

Compile to JS file using TSC command

This function requires a string to be passed as an argument. How to pass in other types and compile an error

(1) The original data type andAnytype

let isDone: boolean = true

let age: number = 20

let firstName: string = 'Axton'
let message: string = `hello ${firstName}`
message = null    // null and undefined are subtypes of any type

let n: null = null
let u: undefined = undefined

let notSure: any = 20   // If you are not sure what type of argument is being passed, you can use any (not recommended)
notSure = 'maybe a string'
notSure = true

notSure.myName
notSure.getName()
Copy the code

(2) Arrays and tuples

let arrOfNumber: number[] = [1.2.3]   // Define an array of type number
arrOfNumber.push(3)

function test () {
  console.log(arguments)    / / array
}

let user: [string.number] = ['Axton'.20]    // Define tuples that can only correspond to data types one by one
user.push('Tang')   // Can only be one of the above two data types
Copy the code

(3) Interface

Describes the shape of an object

interface Person {
  name: string.// Define attributes for the interfaceage? :number    // How can this attribute be optional and changed to '? :' How can this be implemented without an error
  readonly sex: string    // Set the read-only property
}

let Axton: Person = {   // Declare variables to implement this interface
  name: 'Axton Tang'.// Must be consistent with the attributes of the interface
  age: 20.sex: 'male'
}

Copy the code

(4) Function

const add = (x: number.y:number, z? :number) :number= > {
  if (typeof z === 'number') {
    return x+y+z
  } else {
    return x+y
  }
}

add(1.2.3)

interface ISum {    // Use interfaces to describe function types
  (x: number.y: number, z? :number) :number
}

let add2: ISum = add
Copy the code

(5) Type inference combines type and type assertion

1. Type inference: if the type of a variable is not explicitly specified, TS will infer the type of the variable based on your first assignment, and will report an error if the variable is assigned to another type

2. Joint type:

When a variable is a union type, only properties and methods common to the union type can be used

let str = 'string'

// Union type
let numberOrString: number | string
numberOrString = 123
numberOrString = 'Axton'
Copy the code

Type assertion:

// Since you can only use common attributes and methods after using federated types, sometimes you can use type assertions if you want to use unique methods
/ / method
function getLength(input: string | number) :number {
  const str = input as string		// Note that it is not converted to this type here
  if (str.length) {
    return str.length
  } else {
    const number = input as number
    return number.toString().length
  }
}

/ / method 2
//type guard
function getLength2(input: string | number) :number {
  if (typeof input === 'string') {		// Use the condition judgment to automatically narrow the scope, can use the type specific method
    return input.length
  } else {
    return input.toString().length
  }
}
Copy the code

(6)

class Animal {
  readonly name: string;
  constructor(name) {
    this.name = name
  }
  run() {
    return `The ${this.name} is running`}}const snake = new Animal('lily')
console.log(snake.run())

class Dog extends Animal {
  bark() {
    return `The ${this.name} is barking`}}const xiaobao = new Dog('xiaobao')
console.log(xiaobao.run())
console.log(xiaobao.bark())

class Cat extends Animal {
  static categories = ['mammal']
  constructor(name) {
    super(name)
    console.log(this.name)
  }
  run() {
    return 'Meow, ' + super.run()
  }
}
const maomao = new Cat('maomao')
console.log(maomao.run())
console.log(Cat.categories)
Copy the code

(7) Classes and interfaces

interface Redio {
  switchRedio(trigger: boolean) :void;
}

interface Battery {
  checkBatteryStatus(): void;
}

interface RedioWithBattery extends Redio {		// Interface inherits interface
  checkBatteryStatus(): void;
}

class car implements Redio {
  switchRedio(trigger: boolean){... }}class cellPhone implements RedioWithBattery {
  switchRedio(trigger: boolean){... }checkBatteryStatus(){... }}Copy the code

(8) Enumeration (Enum)

enum Direction {		// Const before enum is a constant enumeration
  up = 10.// The value starts at 0 by default and increments from 10
  down,
  left,
  right
}

console.log(Direction.up)   / / value to 10


enum Direction2 {
  str1 = 'STR1',
  str2 = 'STR2'
}

const value = 'STR1'
if (value === Direction2.str1) {
  console.log('go str1')}Copy the code

(9) Generics

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

const result = echo(true)   // The type can only be determined when the argument is passed. What type is passed in and what type is returned

function swap<T.U> (tuple: [T, U]) :U.T] {
  return [tuple[1], tuple[0]]}const result2 = swap(['string'.123])
Copy the code

Constraints of generic

Because the type of the parameter is not determined when using generics, you cannot directly use the methods and attributes of the parameter type passed in. Instead, you can use the methods and attributes of the interface you want to use when using generics.

interface IWithLength {
  length: number
}

function echoWithLength<T extends IWithLength> (arg: T) :T {
  console.log(arg.length)
  return arg
}

const str = echoWithLength('str')
const obj = echoWithLength({length: 10.width: 20})
const arr = echoWithLength([1.2.3])
Copy the code

The use of generics in classes

class Queue<T> {
  private data = []
  push (item: T) {
    return this.data.push(item)
  }
  pop () {
    return this.data.shift()
  }
}

const queue = new Queue<number>()

queue.push(123)
console.log(queue.pop().toFixed())
Copy the code

The use of generics in interfaces

interface KeyPair<T, U> {
  key: T,
  value: U
}

let kp1: KeyPair<string.number> = {key: 'string'.value: 20}
let kp2: KeyPair<number.string> = {key: 10.value: 'str'}

// Two ways to define an array of type number
let arr1: number[] = [1.2.3]
let arr2: Array<number> = [1.2.3]
Copy the code

(10) Type aliases, literals, and cross types

// Type alias
type plusType = (x: number, y: number) = > number
let sum: plusType
const result1 = sum(1.2)

type numOrStr = number | string
let result2: numOrStr = 'str'
result2 = 123

/ / literal
const str: 'name' = 'name'
const number: 1 = 1

type Directions = 'up' | 'down' | 'left' | 'right'
let toWhere: Directions = 'up'

// Cross types
interface IName {
  name: string
}

type IPerson =  IName & {age: number}
let person: IPerson = {name: 'Axton'.age: 20}
Copy the code

(11) Declaration document

When using some third-party libraries, TS does not know what file we are importing, so it will report an error

At this point, you need to define the declaration file

// Declaration files are usually placed in files ending with.d.ts
declare var jQuery: (selector: string) = > any;

// Example: Use
jQuery('#foo')
Copy the code

Many third-party libraries have a ready-made declaration file, which we can install via NPM