TypeScript

TypeScript is a JavaScript based language that overcomes the limitations of JS’s own type system and greatly improves the reliability of code.

Contents summary

  • Strong versus Weak typing (type safety)
  • Static versus dynamic typing (type checking)
  • JavaScript has its own type system
  • Flow Static type check scheme
  • TypeScript language specifications and basic applications

The type system

Strong type vs. weak type

  • Difference: whether implicit conversions of data types are allowed arbitrarily
  • Strong types have stronger type constraints, while weak types have few constraints. A strong type does not allow any implicit conversion of data, while a weak type is allowed. For example, in JS, a numeric type and a string type can be summed up, resulting in a new string, and the program does not report an error. Strong typing is syntactically related, and errors are reported at compile time if the type constraint is not met, rather than at run time.

Static typing vs. dynamic typing

  • Difference: Whether the type of a variable can be changed at any time
  • When a statically typed variable is declared, the type is explicit. After the declaration, the type cannot be changed. Dynamically typed variables are typed at run time and can change at any time. You can say that variables are untyped, whereas variable values are typed, and JavaScript is dynamically typed

Note: Strong typing is not the same as static typing, and weak typing is not the same as dynamic typing because of the different dimensions.

JavaScript type system features

  • Weak type
  • Dynamic type
  • There is no type limitation, it is “capricious”, it loses the reliability of the type system, and it is “unreliable”.
  • Background: The early use of JavaScript is relatively simple, there is no need to set up a complex type system, JavaScript as a scripting language has no compilation

Weak type problems

  • Syntax errors in code are discovered at runtime
  • The type uncertainty results in changes in function functionality, such as a sum resulting in string concatenation

The advantage of strong typing

  • Mistakes are exposed earlier
  • The code is smarter, the code is more accurate
  • Refactoring is more robust
  • Reduce unnecessary type judgments

Summary of the Flow

Flow: Static type checker for JavaScript. It was launched by FaceBook in 2014 to compensate for weak typing in JavaScript

How it works: Add type annotations to the code to mark the types of variables or parameters, Flow checks the type anomalies in the code according to type annotations, thus realizing the type checking of data at the coding stage, avoiding the exposure of exceptions at runtime

function sum (a: number, b: number) {
  return a + b
}
Copy the code

Summary of TypeScript

Based on JavaScript, it is the superset of JavaScript. The so-called superset is the expansion of JavaScript on the original basis, supporting type checking and supporting ES new features.

Advantages:

  1. Support type checking to expose errors in advance
  2. Support ES new features, development no longer need to rely on Bable
  3. Good compatibility, can be compiled into the earliest ES3, any kind of JavaScript runtime environment support
  4. Compared to Flow (JS static type checking tool), as a complete development language, more powerful, more complete ecosystem, TypeScript support is very good Microsoft tools, large front-end frameworks (Angular/Vue. JS 3.0) have started to use TS development. TS is the second largest language in the front-end domain

Disadvantages:

  1. The language itself adds many concepts, such as interfaces, generics, enumerations… , there is a learning cost, but TS is progressive
  2. At the beginning of the project, TS will add some development costs

Principle of selection: small project, short cycle, flexible can use JS; TS is suitable for large projects with long cycle development and iterative maintenance.

Quick learning

Installation:

yarn add typescript --dev
Copy the code

Create a new 01-getting-started. Ts file in the root directory of the project

Run:

yarn tsc 01-getting-started.ts
Copy the code

A 01-getting-started. Js file is automatically generated in the project root directory for ts compilation

The configuration file

TS can compile not only individual files but also entire projects

(1) Initialize the configuration file

yarn tsc --init
Copy the code

(2) After executing the command, the root directory of the project will generate a tsconfig.json file, which is the CONFIGURATION file of TS, and then modify the relevant configuration according to the annotations

(3) Run the command line to compile

yarn tsc
Copy the code

The original type

// Raw data type

const a: string = 'foobar'

const b: number = 100 // NaN Infinity

const c: boolean = true // false

// const d: Boolean = null // In strict mode, initial values of string, number, and Boolean cannot be null

const e: void = undefined

const f: null = null

const g: undefined = undefined

const h: symbol = Symbol(a)/ /? Json target: ['es5'], lib: ['es2015', 'DOM']
Copy the code

The standard library

Standard library: the declaration file corresponding to the built-in object. If the code uses the built-in object, it must reference the corresponding standard library. Otherwise, TS will report an error if it cannot find the type

Reference method: By modifying the target or lib options in tsconfig.json

The Object type

In TS, Object refers not only to ordinary Object types, but to all non-primitive types (Array, Object, Function).

const foo: object = function () {} / / [] {}

const obj: { foo: number.bar: string } = { foo: 123.bar: 'string'.more: 123} Object type constraints require that the structure of the assigned object and the structure of the type be exactly the same, no more, no less. Generally, the interface defines the object type constraints
Copy the code

An array type

const arr1: Array<number> = [1.2.3] // Indicates that all members are numbers
const arr2: number[] = [1.2.3]
Copy the code

Tuple Type

Special data structures: A meta-ancestor is an array with an explicit data type and amount

const tuple: [number.string] = [18.'zce']
const age = tuple[0]
const name = tuple[1]
const [age, name] = tuple
Copy the code

For example, the useState hook function in React is of the meta-ancestor type

import React, {useState } from'the react'
const [count, setCount] = useState(0)
Copy the code

Enumeration Type (Enum)

Enumeration types can be used when certain values are commonly used in development to represent certain states

enum PostStatus {
	Draft =0,
  Published = 1,
  UnPublishen = 2
}

const post = {
  title: 'The Moon and sixpence'.status: PostStatus.Draft
}

// Note: names and values are used with "=" connections are not ":"

// If the enumeration value is a number, it can not be specified. By default, the enumeration starts from 0

// A common enumeration type that intrudes on developed code and is converted to a bidirectional key-value pair after compilation, as shown in PostStatus:
(function (PostStatus) {
   PostStatus[PostStatus["Druft"] = 0] = "Druft";
   PostStatus[PostStatus["Published"] = 1] = "Published";
   PostStatus[PostStatus["UnPublished"] = 2] = "UnPublished";
})(PostStatus || (PostStatus = {}));

// The purpose is to get the name of an enumeration by value. If you can be sure that your code will not use an indexer to get the name of an enumeration, you can use constant enumeration
PostStatus[0] // => Draft

// Constant enumeration: Const appended to enum is cleared after compilation. Enumerations are replaced by specific values
var post = {
    title: 'The Moon and sixpence'.status: 0 /* Draft */
};
Copy the code

Function types

Type constraints on function parameters and return values

// 1. Function declaration
function foo(a: number, b: number) :string {
  return "It's a function"
}

foo(100.200) // Form participation arguments must be guaranteed to be exactly the same

// Optional argument (must be placed at the end of the argument) : Add? After the argument name. Or set default values for the parameters
function fun1(a: number, b? :number) :string {
  return 'fun1'
}

function fun2(a: number, b: number = 10) :string {
  return 'fun1'
}

// The rest of the argument must be placed at the end of the argument.
function fun3(a: number. rest:number[]) :string {
  return 'fun3'
}

// -------------------------------------

// 2
const bar: (a: number, b: number) = > string = function (a: number, b: number) :string {
  return "It's another function"
}
Copy the code

Any type (Any)

Any is still a dynamic type. TS does not check the type of Any.

function stringify(value: any) {
  return JSON.stringify(value)
}

let foo:any = 'string'
foo = 100 // There is no syntax error
foo.bar() // There is no syntax error
Copy the code

Void type

If a method does not return a value, the method’s return value type is Void

function func() :void {
	console.log("Tribe of ants")}// The above function does not return any value, so the return value type is void
Copy the code

The value of a void variable is limited to undefined and null

let a: void = null
let b: void = undefined
Copy the code

Void is a child of any and the parent of null and undefined

let ant: void = null
let str: string = ant
Void cannot be assigned to a string
Copy the code

Implicit type inference

If the variable is not annotated with a type annotation, TS will infer the type of the variable based on the use of the variable, and if TS cannot infer the type of the data is Any

let age = 18 // Age is number
age = 'string' // An error will be reported

let foo // Declare variables without initialization and implicitly infer that foo is any
foo = 100 / / is not an error
foo = 'string' / / is not an error
Copy the code

Types of assertions

In special cases, TS cannot infer the type of a variable. Assertion explicitly tells TS the data type of a variable to assist TS to determine the data type

Note: There is a fundamental difference between a type assertion and a conversion. A type assertion is a concept at compile time, while a conversion is a concept at run time. After compile time, the type assertion is gone

// Assume that the NUMS comes from an explicit interface
const nums = [10.20.30.40.50]

const res = nums.find(i= > i > 0)

// const square = res * res

Type assertion syntax 1
const num1 = res as number

// Type assertion syntax 2 (conflicts with JSX tags, can't be used under JSX)
const num2 = <number>res
Copy the code

TypeScript Interface (Interface)

Norms, contracts; Used to specify the structure of an object (what members, what types of members)

// Interface can only be used to specify the structure of the object. There is no trace of interface in the compiled JS file
interface Post {
  title: string // Members should be separated by semicolons, which can be omitted
  content: stringsubtitle? :string // Optional member: Add? After the member name.
  readonly author: string // Read-only member: Add readonly to the front of the member name. It cannot be changed after initialization
}

function printPost(post:Post) { // Explicitly requires that the post passed in must have two string members: title and content
  console.log(post.title)
  console.log(post.content)
}

printPost({
  title: 'Hello TypeScript'.content: 'A javascript surperset'
})

// ---------------------
// Dynamic members: we can only specify the member name and the type of the member
interface Cache { // Specifies only string keys
  [prop: string] :string
}

const cache: Cache = {}
cache.foo = 'value1'
cache.bar = 'value2'

Copy the code

The TypeScript class

The basic use

Function: Describe the abstract features of a concrete object

Before ES6, function + prototypes were used to simulate implementation classes

After ES6, there are specialized classes for JS

TS enhances the relative syntax of classes

class Person {
    // TS needs to specify the class attributes. The class must have an initial value, which can be set after the = declaration, or dynamically assigned in the constructor
    name: string // = 'init name'
    age: number
  
    constructor (name: string, age:number) {
        // Assign attributes dynamically in the constructor
        this.name = name
        this.age = age
    }

    sayHi(msg: string) :void {
        console.log(`I am The ${this.name}, S{msg}`)}}Copy the code

Access modifier for a class member

Private (Private property that can only be accessed inside the class)

Public (public property, default is public property)

Protected (protected, accessible only within a class or subclass)

If the constructor is set to private, the class cannot be instantiated and cannot be inherited

Class read-only property

Readonly Sets a member to read-only, followed by an access modifier, and can be initialized at declaration time or in a constructor (either), after which it is not allowed to be modified

Classes and interfaces

Interfaces are more abstract than classes. Classes share common characteristics and can be abstracted through interfaces

Eg: Mobile phones and landlines belong to different classes, but they can both make calls and implement the same protocol. The protocol in the program is the interface

An abstract class

An abstract class can contain a concrete implementation. An interface is an abstraction of a member but does not contain a concrete implementation. Abstract classes cannot be instantiated, they can only be inherited, and large classes are usually abstract, like “Animal”.

// Abstract classes are modified with abstract
abstract class Animal {
  eat(food: string) :void {
    console.log('Oink oink eat:${food}`)}abstract run (distance: number) :void // An abstract method does not need a method body. It needs to be implemented in a subclass
}

// An abstract class cannot create a sample, but can only be inherited
// const dog = new Animal() // Error: cannot create abstract class example

class Dog extends Animal {
  run(distance: number) :void {
    console.log('Crawling on all fours:${distance}`)}}const dog = new Dog()
dog.eat('bone')
dog.run(300)
Copy the code

The generic

Functions, interfaces, and classes are defined without specifying specific types, but used with specific types. Purpose: maximum reuse of code

// Generics use: function name add 
      
function creatArray<T> (length: number, value: T) :T[] {
  const arr = Array<T>(length).fill(value)
  return arr
}

const res = creatArray<number> (3.100) / / [100, 100, 100]
const res2 = creatArray<string> (2.'hello') // ['hello', 'hello']
Copy the code

Type declaration

If a third-party module is used in the development, the corresponding type declaration file of the third-party module can not be found. (Error: the type declaration file of the third-party module is not found.)

(1) Declare

import { camelCase } from 'loadsh'
declare function camelCase (input: string) :string
const res = camelCase('hello typed')
Copy the code

(2) Install the third-party type declaration module

npm i @types/modulesName --dev
Copy the code