What is the TypeScript

TypeScript is a free and open source programming language developed by Microsoft. It is an == superset of JavaScript, and essentially adds optional static typing and class-based object-oriented programming to the language.

TypeScript is JavaScript with type syntax, a strongly typed == programming language, and offers the latest JavaScript features. When compiled into code, it eventually becomes JavaScript and can be run anywhere JavaScript is running, such as in a browser, NodeJS, Electron, Deno, etc.

The role of the TypeScript

  1. Avoid problems during development (mistyped methods, etc.)
  2. Good syntax hints (component/function mandatory/optional parameters are clear, etc.)
  3. Form type thinking
  4. The code is more robust and readable
  5. Reduce team communication and documentation

Basic types of

String

let  name: string = 'Wang Tongchao'
Copy the code

Number

let  age: number = 18
Copy the code

Boolean

let isStudy: boolean = true
Copy the code

Undefined Null

let myname: undefined = undefined
let myname: undefined = void 0
let myname: null = null
// strictNullChecks Specifies whether to set undefined and null
// is a subtype of another type
Copy the code

Void

let name: void = undefined
let func: () = > void = () = > {}
Copy the code

Symbol

let myname: symbol = Symbol('Wang Tongchao');
Copy the code

BigInt

let bigNumber: bigint = 10n
Copy the code

Array

let arr: number[] = [1.2.3]
// or
let arr: Array<string> = ['hello'.'wrold']
Copy the code

Tuple

Tuples are like arrays, except that arrays can only define values of fixed types whereas tuples can define values of different types == and the number of elements ==

let tup: [number.string] = [18.'Wang Tongchao']
// The types and quantities defined here must be the same, otherwise an error will be reported
Copy the code

Enum

1. Enumeration of numbers

enum Code{
   success,
   faild,
   noAuth
}
// Compile to JavaScript as
var Code;
(function (Code) {
    Code[Code["success"] = 0] = "success";
    Code[Code["faild"] = 1] = "faild";
    Code[Code["noAuth"] = 2] = "noAuth";
})(Code || (Code = {}));
Copy the code

2. Enumeration of strings

enum Code {
   success = 'SUCESS',
   faild = 'FAILD',
   noAuth = 'NOAUTH'
}
// Compile to JavaScript as
var Code;
(function (Code) {
    Code["success"] = "SUCESS";
    Code["faild"] = "FAILD";
    Code["noAuth"] = "NOAUTH";
})(Code || (Code = {}));
Copy the code

3. Heterogeneous enumeration

enum Code {
    success,
    faild = 'FAILD',
    noAuth = 1,
    error
}
// Compile to JavaScript as
var Code;
(function (Code) {
    Code[Code["success"] = 0] = "success";
    Code["faild"] = "FAILD";
    Code[Code["noAuth"] = 3] = "noAuth";
    Code[Code["error"] = 4] = "error";
})(Code || (Code = {}));
Copy the code

4. Constant enumeration

const enum Code {
    success,
    faild,
    noAuth
}
console.log(Code.success)
// Compile to JavaScript as
console.log(0 /* success */);
Copy the code

Any

Any type is a “subtype” of any, so any is not a top-level type in the type system (the global super type). Extensive use of any makes ts’s type protection obsolete. Unknown types are introduced in TypeScript 3.0

let data: any
data = 18
data = 'Wang Tongchao'
data = () = > { alert('No problem')}// noImplicitAny configures whether implicit any is allowed (ts type inference can infer types)
Copy the code

Unknown

Similarly, any can be defined as any type, but assigning unknown== to other types of == is limited, and calling unknown data == method == also raises an error

let data: unknown
data = 1
data = 'Wang Tongchao'
data = { name: 'Wang Tongchao' }
data = () = > {}

let data1: unknown = data / / no problem
let data2: any = data / / no problem
let data: number = data // error
let data: string = data // error

data.name // error
Copy the code

Never

The never type represents a value that never exists. Usually used when a function throws an exception or returns no value

/ / scenario 1
function fail(msg: string) :never {
  throw new Error(msg);
}

/ / scenario 2
function fn(x: string | number) {
  if (typeof x === "string") {
    // do something
  } else if (typeof x === "number") {
    // do something else
  } else {
    x; // has type 'never'!}}/ / scenario 3
switch(x: 1|2) {
  case 1:
    break
  case 2:
    break
  default:
    const exhaustiveCheck: never = x
    break
}
Copy the code

Literal type

let myname: 'wtc' = 'wtc'
let age: 18|19 = 18
Copy the code

interface

Used to declare types, is an abstraction of behavior

// Declaration type
interface IStudy {
    result: boolean
}
interface ITest {
    name: string
    readonly age: number / / read-onlyisDone? :boolean / / is optional
    goSleep: () = > void
    goStudy: (type: string) = > IStudy
    goEat: (x: number, y: string) = > boolean
}

// Interfaces are merged automatically
interface ITest {
    goAway: () = > void
}

let test: ITest = {
    name: 'Wang Tongchao'.age: 18.isDone: true.goSleep: () = > {},
    goStudy: (type) = > ({ result: true }),
    goEat: function(x, y) {
        this.age = 'the' // error Because age is read-only, it cannot be changed
        return!!!!! (x && y) },goAway: () = > void
}
Copy the code

1. Interface Inheritance interface

interface ITest0 {
    goAway(x: number) :number
}

interface ITest1 {
    name: string
}

/ / single inheritance
interface ITest2 extends ITest1 {
    age: number
}

/ / multiple inheritance
interface ITest3 extends ITest1, ITest0 {}

let data: ITest2 = {
    name: 'Wang Tongchao'.age: 18
}

let data1: ITest3 = {
    name: 'Wang Tongchao'.goAway: (x) = > x
}
Copy the code

2. Interface inheritance classes

class Test1 {
    name = 'Wang Tongchao'
    age = 18
    goAway(x: number) {
        return x
    }
}

class Test2 {
    goEat(){}}interface ITest2 extends Test1, Test2 {
    // age: string Cannot change the type of an existing field in class
    mood: 'good'| 'bad'
}

let data: ITest2 = {
    name: 'WTC'.age: 19.goAway: (x) = > x,
    mood: 'good'.goEat: () = > undefined
}
Copy the code

3. Classes implement interface/type aliases

interface ITest1 {
    name: string
    age: number
    goAway(x: number) :number
}
interface ITest2 {
    mood: string
}

class Test implements ITest1.ITest2 {
    name = 'Wang Tongchao'
    age = 18
    mood = 'good'
    goAway(x: number) {
        return x
    }
}
Copy the code

4. Classes inherit classes to implement interfaces

interface ITest {
    name: string
    age: number
    goAway(x: number) :number
}

class A {
    name = 'Wang Tongchao'
}

// If the parent class is already implemented, the child component can choose not to implement it
class B extends A implements ITest {
    age = 18
    goAway(x: number) {
        return x
    }
}
Copy the code

The joint type

Is equal to or

interface ITest {
    name: string | null // Define name as a string or null
}

// The parameter x may be of type number or undefined
function test1 (x: number | undefined) {}
Copy the code

Cross type

Equivalent to merger

interface ITest1 {
    name: string
}

interface ITest2 {
    age: number
}

type Itest = ITest1 & ITest2

let data: ITest1&ITest2 = {
    name: 'Wang Tongchao'.age: 18
}
/ / or equivalent
let data: Itest = {
    name: 'Wang Tongchao'.age: 18
}

// Example 2: merge base type attributes of the same name. Different types are merged to never
interface IA {
    type: number
    age: number
}
interface IB {
    type: string
    age: number
}

type IC = IA & IB

let data: IC = {
    type: 1.// error Type 'number' is not assignable to type 'never'
    age: 18
}

// Example 3 merges attributes of non-base types with the same name
interface IA {
    type: {
        name: string
    }
    age: number
}
interface IB {
    type: {
        age: number
    }
    age: number
}

type IC = IA & IB

let data: IC = {
    type: { // The attributes are merged here
        name: 'Wang Tongchao'.age: 18
    },
    age: 18
}
Copy the code

Type the alias

It acts as an interface to rename multiple types to a single type

type ITest1 = string | number | undefined

interface ITest2 {
    name: string
}
interface ITest3 {
    age: number
}
type ITest4 = ITest2 & ITest3

let data: ITest4 = { name: '12'.age: 1 }
Copy the code

Types of assertions

Used when you think that the type of the value in the current environment is more accurate than TypeScript inferred

let age: number = (myname as string).length
// or it is best not to use the following notation in JSX
let age: number = (<string>myname).length


function iTakeFoo(foo: 'foo') {}
const test = {
  someProp: 'foo' as 'foo' // No type assertion is inferred to string
}

iTakeFoo(test.someProp)
Copy the code

Not empty assertion

function test(func: (() => void) | undefined) {
    func!()
}

/ / sample 2
let test1: string | undefined | null
let test2: string = test1!

// Example 3 states that a variable must have a value
lettest1! :number
// TODO
let test2 = test1 * 2
Copy the code

The index sign

Specifies the type of index. Index signatures can be numeric or string indexes

// String index
interface IData {
    [key: string] :string
}

// Numeric index
interface IData2 {
    1: 'Wang Tongchao'
    [key: number] :string
}

let data: IData = {}
data.name = 'Wang Tongchao'
Copy the code

Type of protection

Type protection allows you to use a narrower range of object types

// typeof
function test1(x: string | number) {
    if (typeof x === 'string') {
        // In this scope x is inferred to be string
        // We can use string methods instead of number methods}}// instanceof
class Foo {
  foo = 123;
  common = '123';
}

class Bar {
  bar = 123;
  common = '123';
}

function doStuff(arg: Foo | Bar) {
  if (arg instanceof Foo) {
    console.log(arg.foo); // ok
    console.log(arg.bar); // Error
  }
  if (arg instanceof Bar) {
    console.log(arg.foo); // Error
    console.log(arg.bar); // ok}}// in
interface A {
  x: number;
}

interface B {
  y: string;
}

function doStuff(q: A | B) {
  if ('x' in q) {
    // q: A
  } else {
    // q: B}}// literal type protection
type Foo = {
  kind: 'foo'; // The literal type
  foo: number;
};

type Bar = {
  kind: 'bar'; // The literal type
  bar: number;
};

function doStuff(arg: Foo | Bar) {
  if (arg.kind === 'foo') {
    console.log(arg.foo); // ok
    console.log(arg.bar); // Error
  } else {
    // It must be Bar
    console.log(arg.foo); // Error
    console.log(arg.bar); // ok}}Copy the code

Type inference

TypeScript automatically inferences types from code

interface IT1 {
    type: 1.name: 'Wang Tongchao'
}
interface IT2 {
    type: 2.age: 18
}

function test(data: IT1|IT2) {
    // Automatically infer IT1 type
    if (data.type === 1) {
    console.log(data.name)
    }
}

let myname = 'Wang Tongchao' // let myname: string
let age = '18' // let age: number

// function goAway(x: number, y: number): number
function goAway(x: number, y: number) {
    return x + y
}
Copy the code

overloading

Example 1: function overload
function test(x: number) :void
function test(x: number, y: number) :string
function test(x: number, y: number, z: number) :number
function test(x: number, y? :number, z? :number) :any {
    if (y ! = =undefined) {
        return String(y)}else if (y ! = =undefined&& z ! = =undefined) {
        return x + y +z}}test(1) / /function test(x: number) :void
test(1.2) / /function test(x: number, y: number) :string
test(1.2.3) / /function test(x: number, y: number, z: number) :number// Example 2 class overloadclass A {
    goSleep(x: number, y: number) :void
    goSleep(x: string, y: string) :void
    goSleep(x: number) :void
    goSleep(x: number|string, y? :number| string) {
        if (y ! = =undefined) {
            if (typeof y === 'number') {} else{}}else {
            if (typeof x === 'number') {} else{}}}}const AInstance = new A()
AInstance.goSleep(1)
Copy the code

The generic

Used in cases where you do not need to rely on the actual type of an object, but still want to provide mandatory type constraints to extend possible future data types.

1. Generic interfaces

interface ITest<T> {
    name: string
    goAway: (x:T) = > T
}

const data: ITest<string> = {
    name: 'Wang Tongchao'.goAway(x) { // (property) ITest<string>.goAway: (x: string) => string
        return x
    }
}
data.goAway(1) // error
Copy the code

2. Generic type alias

type ITest<T> = {
    name: string
    goAway: (x:T) = > T
}

const data: ITest<string> = {
    name: 'Wang Tongchao'.goAway(x) { // (property) ITest<string>.goAway: (x: string) => string
        return x
    }
}

data.goAway(1) // error
Copy the code

3. Generic functions

function test<T.K> (para: T) :K[] {
    // ToDo
    return []
}

test<number.string> (1)
Copy the code

4. A generic class

Generic classes cannot constrain static members

class A<T> {
    myname: T[]
    constructor() {
        this.myname = []
    }
    // static goTes(): T {} // generic classes cannot constrain static members
    goAway(): T {
      return this.myname[0]}}new A<string> ()Copy the code

5. Constraints (inheritance) and defaults for generics

interface ILength {
  length: number;
}

function identity<T extends ILength.K=string> (arg: T, arg2: K) :T {
  console.log(arg.length); / / no problem
  return arg;
}

identity('12'.12)
Copy the code

6. Using generics incorrectly

// It has no meaning
interface ITest<T> {
    (x: T): void
}

type ITest = <T>(x:T) = > void
Copy the code

class

  • Public – Public (default). Classes can be used, instances can be used, and can be inherited
  • Static-static, class can use, instance cannot use, can be inherited
  • Readonly – Read-only, the same as public except that it cannot be modified
  • Private-private, used only by the class itself. Instances cannot be used, nor can they be inherited (this class cannot be instantiated or inherited if added to constrctor)
  • Protected – Protected, used only in classes and subclasses, not in instances (if applied to constrctor, the class cannot be instantiated, only inherited)
class A {
  public name: string
  private age: number
  protected mood = 'good'
  readonly study = 'day'
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  sayAge() {
    console.log(this.age)
  }

  static goEat() {
    console.log('goEat')
  }
}

A.goEat()
let AInstance = new A('ts'.18)
let a = AInstance.name
let b = AInstance.sayAge()
let c = AInstance.study
// AInstance. Study = 'month' // error The read-only attribute cannot be modified
// AInstance. Age // error private property, instance cannot be called
// AInstance. Mood // error protected property, cannot be called by instance


class B extends A {
  constructor() {
    super('ts'.18)}goTest() {
    // console.log(this.age) // Error private variables cannot be inherited
    console.log(this.mood) // Protected variables can be inherited
  }
}

B.goEat()
let BInstance = new B()
let d = BInstance.name
let e = BInstance.sayAge()
let f = BInstance.study
// binstance. study = 'month' // error The read-only attribute cannot be modified

Copy the code

An abstract class

Classes declared using the abstract keyword are called abstract classes. An abstract class containing one or more abstract methods cannot be instantiated, but can only be inherited.

// An abstract class can specify concrete methods or only abstract methods.
// Specify the specific method, the subclass does not need to implement.
// Specify an abstract method that subclasses need to implement.
abstract class A {
    myname: string
    age: number
    constructor(name: string, age: number) {
        this.myname = name
        this.age = age
    }
    goSleep() {
        console.log('goSleep')}abstract goAway(): void
}

class B extends A {
    constructor(name: string, age: number) {
        super(name, age)
    }
    goAway(){}}const BInstance = new B('Wang Tongchao'.18)
BInstance.goSleep()
BInstance.goAway()
Copy the code

Configuration file (tsconfig.js)

Configuration Details

  • Files – Sets the name of the file to compile
  • Include – Sets files to be compiled and supports path pattern matching
  • Exclude – Sets files that do not need to be compiled and supports path pattern matching
  • Extends – Extends configuration path (can inherit from other configurations)
  • References – Introduce additional projects
  • CompilerOptions – Sets the options related to the compilation process
/* Visit https://aka.ms/tsconfig.json to read more about this file */
{
  // "file": [],
  // "extends": "",
  // references: [{path: ''}]
  "include": ["./src"]."exclude": []."compilerOptions": {
    
    /* Projects */
    // "incremental": true, /* Enable incremental compilation */
    // "composite": true, /* Turn on the constraint for the composite project */
    // "tsBuildInfoFile": "./", /* Specifies where the incremental compiled file (.tsbuildinfo) is stored */
    / / "disableSourceOfProjectReferenceRedirect" : true, / * disable composite project source files rather than a declaration file * /
    // "disableSolutionSearching": true,                 /* 忽略(编辑器对于)复合项目中的引用/跳转,提高响应能力 */
    / / "disableReferencedProjectLoad" : true, / * disable all project of the automatic loading (if the project is bigger, ts will all available project loaded into memory, open this function, dynamic loading the editor will open file only) * /

    /* Language and Environment */
    "target": "ES5"./* Specify the ECMAScript target version: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES7'/'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ESNext' */
    // "lib": [], /* Specifies the library file to be included in the compilation */
    // "JSX ": "preserve", /* Specify JSX code generation: 'undefined'(default), 'preserve', 'react', 'react-jsx', 'react-jsxdev', 'react-native' */
    // "experimentalDecorators": true, /* Enable ESMAScript decorator support */
    // "emitDecoratorMetadata": true, /* Enable decorator metadata support */
    // "jsxFactory": "", /* specifies the JSX compile-time factory function e.g. 'react. createElement' or 'h' */
    // "jsxFragmentFactory": "", /* Specifies JSX compilation of empty tags
    // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
    // "reactNamespace": "", /* Specifies the object to be called by the createElement target React. The default is React */
    // "noLib": true, /* Disables the inclusion of any library files
    // "useDefineForClassFields": true, /* Defines class fields, TS has the same syntax as the latest TC39 syntax, but different runtime behavior. For ES2022 and ESNext */

    /* Modules */
    "module": "CommonJS"./* Specify the module System to use CommonJS, UMD, AMD, ES6, ES2015, ES2020, None, ESNext, System*/
    // "rootDir": "./", /* Specify the project root directory */
    // "moduleResolution": "node", /* specify the moduleResolution policy 'node'(node.js) or 'classic'(used before TypeScript 1.6) */
    // "baseUrl": "./", /* Specifies the base directory for resolving non-relative module names */
    // "Paths ": {}, /* Specifies the module name to the list of baseUrl based pathmaps */
    // "rootDirs": [], /* Specify multiple project root directories */
    // "typeRoots": [], /* Specifies the type declaration folder, default node_modules/@types */
    // "types": [], /* Specifies the declaration package to load */
    // "allowUmdGlobalAccess": true, /* Allows modules to access UMD variables */
    // "resolveJsonModule": true, /* Allow to import JSON files */
    // "noResolve": true, /* stop checking 'import', 'require' s or '
      
       ' */
      

    /* JavaScript Support */
    // "allowJs": true, /* Allows compiling js files */
    // "checkJs": true, /* Allows checking for js file errors */
    // "maxNodeModuleJsDepth": 1, /* Specifies the maximum folder depth for checking JavaScript files from node_module. Only for 'allowJs: true' */

    /* Emit */
    // "declaration": true, /* Generates the corresponding.d.ts file */
    // "declarationMap": true, /* Generates the sourcemap file for.d.ts */
    // "emitationonly ": true, /* Generates only.d.ts files, not js files */
    // "sourceMap": true, /* Generate js sourceMap file */
    // "outFile": "./", /* Merge output files into one file */
    "outDir": "./dist"./* Specifies the output directory */
    // "removeComments": true, /* Remove all compiled comments */
    // "noEmit": true, /* Does not generate output file */
    // "importHelpers": true, /* Allows auxiliary functions to be imported from tslib (this allows the code size to be reduced, preventing it from being implemented everywhere it is used) */
    // "importsNotUsedAsValues": "remove", /* Specifies the behavior when import is used only as a type. The optional values are 'remove', 'preserve', 'error' */
    // "downlevelIteration": true, /* Allows more accurate conversion to lower version JS code (resulting in too much code) */
    // "sourceRoot": "", /* Specifies the root path for the debugger to find source code */
    // "mapRoot": "", /* Specifies that the debugger should locate the source map file path */
    // "inlineSourceMap": true, /* Allows the source map file to be written to the js line */
    // "inlineSources": true, /* Allows the original content of.ts to be included as a string in the source map (sourceMap or inlineSourceMap is required) */
    // "emitBOM": true, /* Compiled files write utF-8 byte order flags (preferably not turned on unless there is a good reason) */
    // "newLine": "CRLF ", /* Specifies the line break of the compiled file. Optional parameters CRLF, lf */
    // "stripInternal": true, /* Allows disabling declarations containing '@internal' in JSDoc comments */
    // "noEmitHelpers": true, /* Allows you to disable helper functions in tslib, but requires you to implement the related functions */
    // "noEmitOnError": true, /* Allows compilation to stop if type errors are reported */
    // "preserveConstEnums": true, /* Allows constant enumeration */
    // "declarationDir": "./", /* Specifies the directory of the declaration file */

    /* Interop Constraints */
    // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
    / / "allowSyntheticDefaultImports" : true, the default import / * allow mergers, such as the import * as the React from "React" written on the import the React from "React" * /
    "esModuleInterop": true./* Enable compatible esM import CJS export code */
    // "preserveSymlinks": true, /* Open preserveSymlinks */
    "forceConsistentCasingInFileNames": true./* Enable case-sensitive file name */

    /* Type Checking */
    "strict": true./* Enable strict type checking */
    // "noImplicitAny": true, /* Enable implicit any error */
    // "strictNullChecks": true, /* enable strict null and undefined checks (if not, null and undefined are subtypes of all types) */
    // "strictFunctionTypes": true, /* Enable strict function type checking */
    StrictBindCallApply: true, /* Enable call, apply, bind parameters check */
    / / "strictPropertyInitialization" : true, open strict / * property initialization (open after will check statement in the constructor of a class type but uninitialized variables is an error) * /
    // "noImplicitThis": true, /* Enable this for any error */
    // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
    // "alwaysStrict": true, /* Turn on strict mode to check each module and add 'use strict' */ to each file
    // "noUnusedLocals": true, /* Error */
    // "noUnusedParameters": true, /* Error if the function parameters are not used */
    / / "exactOptionalPropertyTypes" : true, open strict optional parameter / * property inspection (after opening, optional parameters cannot be assigned for undefined) * /
    // "noImplicitReturns": true, /* Enable implicit return value error (function may return value or may not return value error) */
    / / "noFallthroughCasesInSwitch" : true, / * open case through writing * / in the switch is prohibited
    // "noUncheckedIndexedAccess": true, /* Enable the index signature containing undefined */
    // "noImplicitOverride": true, /* Override is required to enable a subclass to override its parent class */
    / / "noPropertyAccessFromIndexSignature" : true, / * an open for signature key, undefined error * /
    // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
    // "allowUnreachableCode": true, /* Enable code that will never be executed (if else code that will not be executed after enabled will not be reported) */

    /* Completeness */
    // "skipDefaultLibCheck": true, /* Skip the default library declaration file type check */
    "skipLibCheck": true                                 /* Skip type checking for.d.ts declaration files */}}Copy the code

Reference: TS official website: www.typescriptlang.org/ Po: juejin.cn/post/684490… Book: << Understanding TypeScript in Depth >>