TypeScript starter ~ suitable for beginners to learn quickly.

preface

Hello everyone, this article is a summary of my learning TypeScript.

The current version only writes about the basic use of typeScript, modules, namespaces, modifiers, etc. when summarizing, I always feel that the case is a little pale. I will summarize and output it in the following ts project demo.
I study by watching teaching videos and ts official documents. For the obscure parts in the learning process, I will also check the experience Posts sent by some big guys for absorption.
The original intention of sending this article is to deepen your impression and output your learning content to a certain extent.
Of course, my summary as a chicken dish is not in place. If you find a problem, I hope you can point it out frankly. I will correct it in time. Thank you for your support. ღ (´ᴗᴗღ) comparison Center

Part 01 - TypeScript

TypeScript is a programming language developed by Microsoft and a superset of JavaScript.
TypeScript extends the syntax of, so any existing JavaScript program can run in the TypeScript environment. TypeScript is designed for the development of large-scale applications and can be compiled into JavaScript.
The learning cost of TypeScript is not as large as expected. As a progressive programming syntax, you can write JavaScript code directly in the early stage, and then add a new feature by learning to understand a feature.

Part 02 - installing TypeScript and basic commands

Install TypeScript

npm i typescrpit --dev

Execute the ts file and compile it into a js file

tsc .\getingTs.ts

Perform profile initialization

tsc -- init

Chinese error reporting prompt

tsc -- locale zh-CN

Part 03 - TypeScript configuration file

tsconfig.json
If a tsconfig.json file exists in a directory, it means that this directory is the root directory of the TypeScript project.   The tsconfig. JSON file specifies the root file and compilation options used to compile this project

directory structure

---- src/ 
    ---- dist/ 
       |---- index.js // Compiled js file
    |---- index.ts // Entrance to the entire tool library
    |---- tsconfig.json//configuration file

Common configuration items – because there are too many, only common configuration items are listed
See official documents for details
https://www.tslang.cn/docs/handbook/tsconfig-json.html

{
  "compilerOptions": {
    "target": "ES5",             // Target language version
    "lib": [ "es5","es2015"],    // Standard library declaration
    "module": "commonjs",        // Specifies the template standard for generating code
    "noImplicitAny": true,       // Implicit any type is not allowed
    "removeComments": true,      // Delete Note  
    "preserveConstEnums": true,  // Keep const and enum declarations
    "sourceMap": true            // Source code mapping to generate the sourceMap file of the target file
    "rootDir": "src",            // Entry folder
    "rootDirs": ["src","src/class",],   // Set multiple entry folders
    "outDir": "dist",            // Compiled output folder
    "strictNullChecks": true,    // Check whether the variable cannot be null
    "experimentalDecorators": true      // Support decorator features
  },
  "files": [   // Specifies the file to be compiled
    "./src/index.ts"  
  ]
}

Part 04 - TypeScript basic data type

TypeScript supports almost the same data types as JavaScript. In addition, it also provides practical enumeration types for our convenience.

Boolean boolean type

const doBoolean: boolean = false; // true

Number value type

In addition to constants, NaN, Infinity and floating-point numbers are supported for the Number type specified in ts, including decimal, hexadecimal, binary and octal literal quantities.

const doNumber: number = 1; 
const doNaN: number = NaN;
const doInfinity: number = Infinity;
const doHex: number = 0xf00d

Sring string type

In addition to identifying normal strings, Template Strings and splicing strings can also be used normally, and can also be defined in combination with other variables.

const doString: string = `foo`; 
const testString: string = `foo${doString}and${doNumber + 1}`;
const spliceString: string = 'foo'+doString+'and'+doNumber + 1;

Object object type

Object does not represent ordinary object types, but refers to all non primitive types.
That is, types other than number, string, boolean, symbol, null or undefined.

This means that when defined as an object type, all original types are not specified.

Error: const foo: object = 123; //Type 'number' cannot be assigned to type 'object'.

At the same time, object type does not only refer to ordinary objects

const foo1: object = function name() {};
const foo2: object = [];
const foo3: object = {};

Of course, you can also define objects literally

Note that if you add a specified member, you must ensure one-to-one correspondence, neither more nor less

const foo4: { a: number; b: string } = { a: 1, b: "1" };

Array array type

There are two ways to define an array

Method 1: the element type can be followed by   [] represents an array of elements of this type

const arr1: number[] = [1, 2];
const arr2: object[] = [{}, {}];
const arr3: any[] = [{}, function () {}];

Method 2: it can be represented by array generics

const arr1: Array<string> = ["a", "b"];
const arr2: Array<object> = [{}, {}];
const arr3: Array<any> = [{}, function () {}];

Tuple tuple type

Tuple type allows an array to represent a known number and type of elements, and the types of each element do not have to be the same.

const tuple: [number, string] = [18, "a"];

However, the type and quantity in the array must be consistent with the specified type. If not, an error will be reported.

 const tuple: [number, string] = ["Ethen",18];// Error
 const tuple: [number, string] = [18, "Ethen",'boy'];// Error

enum enumeration type

By default, element numbers are assigned to members starting from 0

enum Enumeration name {Member 1,Member 2,...}
enum Family {Mom,Father,Me} // Mom=0 Father=1 Me=2
enum Color { Red, Green,Blue,}

And the enumeration value is only used as a readable attribute and cannot be changed after definition.
Enumeration is a type that can be used as a type annotation for variables

let c: Color = Color.Green; // c=1

Of course, you can also manually specify the value of the member. However, note that if the initialization assignment is of string type, other members will also be assigned accordingly.

enum num {
  one = 1,
  two , //2
  three , //3
}

Family  {
  Mom = 'emily',
  Father='joe' ,
  Me='mark' , 
}

And we can get its name from the enumerated value. For example, we know that the value is 2, but we are not sure which name it maps to. We can find the corresponding name.

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2]; // Green

Any any type

Any stands for any type, which means that any type can be specified. At the same time, there is no difference between the use of dynamic types and js types, which means that there are still hidden types.

Therefore, any type is generally used to directly let these values pass the compilation stage instead of being checked by the type checker.

For example: document.getElement JSON.stringfy, etc

const flag: any = 'string'; //number undefined ....

Void invalid type

void indicates that there is no type. It is usually used for a function without a return value to specify.

It usually doesn't make any sense because it can only be assigned null and undefined (if the setting cannot be null, it can only be assigned undefined)

function void(): void { 

    console.log("no return"); 
    
}

const noTarget: void = undefined;

Never type

Never types literally represent the types of values that never exist.

//When you throw an exception inside a function, the function will Never have a return value, so it is defined as Never
function error(message: string): never {

  throw new Error(message);
  
}

Part 05 - TypeScript type attribute

In addition to using the above types, TypeScript also has many types of features.

Type inference

In TypeScript, where the type is not specified, type inference will help you specify the type of variable.

let age = 18; // Number
age = 'string' //Error

Of course, if you do not specify Any type when declaring a variable, it will default to Any type, and Any subsequent assignment operation is recognized

let age        // Any
age = 'string' //true
age = 18       //true

Then there is another case, when you use reference data types, such as multiple expression types inside an array.

TypeScript infers the most appropriate generic type based on the type of these expressions

let age=[18,'string',null] // (string | number | null)[]

Type Asserts

When we use TypeScript, you will encounter such a situation that you will know the value type of this variable better than the program.

For example:

const tel = [110, 120, 119];
const emergency = tel.find((i) => i ==110 || i==120); // number | undefined

However, in TypeScript inference, it will be considered as undefined, and we can be sure that it will not occur. In this case, through type assertion, we can tell the compiler that no special circumstances occur.

We usually use two methods to define type assertions

The first: Pass (xxx as type)

let someValue: any = "this is a string"; 
let strLength: number = (someValue as string).length;

Second: Pass (< type > XXX)

let someValue: any = "this is a string"; 
let strLength: number = (<string>someValue).length;

It should be noted here that if it is a jsx file, the writing method of angle brackets may have syntax conflicts, so the inference method of as is recommended

Part 06 - TypeScript Classes

The classes class can be used to describe the abstract features of a class of concrete things

Class definition

The use of classes here is no different from that in js. They contain the same members, namely attributes, constructors and methods.

But it is worth noting that in ts, you must set the initial value in the attribute or constructor when declaring, rather than adding it dynamically in the constructor as in es6

class student {
  name: string;
  age: num;
  constructor(name: string, age: num) {
    this.name = "Zhang San";
    this.age = 18;
  }
  study(course: string): void {
    console.log(`${this.name}this year ${this.age}Years old. He's going to class today ${course}course`);
  }
}

Class inheritance

The class in TypeScript can also inherit the instance of the subclass after the parent class through the subclass, and have the properties and methods in the parent class. Similarly, call the instance of the parent class and get the this of the parent class through super. And you can still implement inheritance through the extends keyword. This enhanced code reusability is preserved in TypeScript.

class student {
 public name: string;
 public age: num;
  constructor(name: string, age: num) {
    this.name = "Zhang San";
    this.age = 18;
  }
  study(course: string): void {
    console.log(`${this.name}this year ${this.age}Years old. He's going to class today ${course}course`);
  }
}

class four extends student {
  constructor(name: string, age: num) {
    super(name, age);
    this.name=name
    this.age=age
  }
  study(grade: string): void {
    console.log(`${this.name}this year ${grade}grade`);
    super.study("language");
  }
}

const Li = new four("Li Si", 22);
Li.study("three");

//Li Si is in grade three this year
//Li Si is 22 years old. He is going to have a Chinese class today

Class modifier

The private property can only be accessed inside the current class

class student {
  private goodStudent: string = "Three good students";
}

class four extends student {
  constructor() {
    super();
    this.goodStudent // The Error property "goodStudent" is private and can only be accessed in class "student".
  }
}

const Li = new four("Li Si", 22);

Li.study("three");
Li.goodStudent // The Error property "goodStudent" is private and can only be accessed in class "student".

However, when we give the private modifier to the constructor, it can neither be inherited nor instantiated externally, but can only be implemented through the static methods inside the class.

class student {
  private constructor(name: string, age: num) {
  }
  static go() {
    return new student();
  }
}

class four extends student { // Cannot extend class' student '. Class constructor is marked private.
}

const Li = new student(); // Cannot extend class' student '. Class constructor is marked private.
const create = Li.go() //Success

Protected # protected attributes can only be accessed inside a class (they can be used in inherited subclasses)

class student {
  protected goodStudent: string = "Three good students";
}

class four extends student {
  constructor() {
    super();
    this.goodStudent // Success
  }
}

const Li = new four("Li Si", 22);

Li.study("three");
Li.goodStudent // The Error property "goodStudent" is private and can only be accessed in class "student".

The function of protected in the constructor is similar to the use of private, but it can be inherited

readonly read-only property read-only property must be initialized in the declaration or constructor

class Student {
  readonly name: string;
  readonly age: number = 18;
  constructor(studentName: string) {
    this.name = studentName;
  }
}

class Four extends Student{
  constructor(name:string){
    super(name)
    console.log(this.name);
  }
}
let three = new Student("Zhang San");
let four = new Four("Li Si");
three.name = "Wang Wu"; // Wrong! Cannot assign to 'name' because it is read-only.
four.name = "Zhao Liu"; // Wrong! Cannot assign to 'name' because it is read-only.

Class accessor

TypeScript supports intercepting access to object members through getters and setters. It can help you control access to object members.

For example, in the following method, we use the set method to judge whether the password is correct before modifying the permission. If the permission cannot be controlled, fullname can still get the old name through get.

let passcode = "password";

class Employee {
  private _fullName: string = "Old name";

  get fullName(): string {
    return this._fullName;
  }

  set fullName(newName: string) {
    if (passcode && passcode == "password") {
      this._fullName = newName;
    } else {
      console.log("Permission update failed");
    }
  }
}

let employee = new Employee();

employee.fullName = "New name";
if (employee.fullName) {
  console.log(employee.fullName);
}

abstract class

Similar to the use method of the interface, it is also the abstraction of members, but different from the interface, the abstract class can contain the implementation details of members.  
Abstract keyword is used to declare and define abstract classes and abstract methods inside abstract classes.

However, an image class cannot be created as an instance. It can only be used after inheritance through the derived subclass, and the super method cannot access the abstract method in the parent class.

abstract class Family {
  people(name: string, relation: string): void {
    console.log(`I ${relation}call ${name}`);
  }
  abstract eat(food: string): void;
}

class Father extends Family {
  eat(food: string): void {
    console.log(food);
  }
}

const father = new Father();
const family = new Family(); // Error! Cannot create an instance of an abstract class.
father.eat("Apple");

Part 07 - TypeScript interface

You can understand an interface as a specification that can be used to standardize the structure and type of objects.

In TypeScript, the function of the interface is to specify which members are included in the object and how the types of these members are specified, so as to formulate specifications.

Interface interface

We use the interface keyword to specify the structure of object members, that is, you must have all members constrained by the interface, and the members must conform to the specified type.

interface rsvrConfig {
  resName: string;
  resCode: number;
  resType: Array<string>;
}

function createRsvr(rsvrData: rsvrConfig) {
  console.log(rsvrData.resName);
  console.log(rsvrData.resCode);
  console.log(rsvrData.resType);
}
const rsvrData = {
  resName: "Huairou Reservoir",
  resCode: 2002011,
  resType: ["PP", "ZZ", "ZQ"],
};

createRsvr(rsvrData);

optional attribute

Optional attributes are equivalent to some attributes that are dispensable and do not affect the use when defining the interface. Then we will add an optional attribute when defining the interface? To show.

interface rsvrConfig {
  resName?: string;
  resCode: number;
}

function createRsvr(rsvrData: rsvrConfig) {
  console.log(rsvrData.resCode);
}

const rsvrData = {
  resCode: 2002011,
};

createRsvr(rsvrData);

One of the advantages of optional attributes is that they can predefine possible attributes. The other advantage is that they can catch errors when referring to non-existent attributes.

For example, the prompt when the attribute name is misspelled

Read only attribute

Some object properties can only change their values when the object is just created. You can use it before the attribute name   readonly to specify the read-only attribute

interface rsvrConfig {
  readonly  resName: string;
}

function createRsvr(rsvrData: rsvrConfig) {
  rsvrData.resName = 'Miyun reservoir ' // !!!  Error read only property
  console.log(rsvrData.resName);
}
const rsvrData = {
  resName: 'Huairou Reservoir',
};

createRsvr(rsvrData);

At the same time, TypeScript has readonlyarray < T > type, which is similar to array < T > except that all variable methods are removed, so it can ensure that the array can no longer be modified after creation:

interface rsvrConfig {
  resType: ReadonlyArray<string>;
}

function createRsvr(rsvrData: rsvrConfig) {
  rsvrData.resType[0] = "Miyun reservoir "; // !!!  Error read only property
  console.log(rsvrData.resType);
}
const rsvrData = {
  resType: ["Huairou Reservoir"],
};

createRsvr(rsvrData);

Function type

In addition to describing ordinary objects with attributes, interfaces can also describe function types. It is equivalent to defining the type of parameter for a function.

The parameters of the function will be checked one by one, and the parameter types at the corresponding positions are required to be compatible.

interface SearchFunc {
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;

mySearch = function (source: string, subString: string):boolean {
  let result = source.search(subString);
  return result > -1;
};

Dynamic type

When you don't know whether your interface needs to add other unknown fields, you can define dynamic types in the form of [auto:type]:type.

interface StringArray {
  [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];
interface StringName {
  [name: string]: string;
}

let nameDate: StringName;

nameDate = {
  Huairou Reservoir: "1",
  Miyun reservoir : "1",
  Heishan reservoir: "1",
};

TypeScript supports two types of index signatures: string and number. You can use both types of indexes at the same time.

nameDate[0] = "Miyun"; 
nameDate["1"] = "Huairou";
// Namedate = {'0': 'Miyun', '1': 'Huairou'}

myArray[0] = "Miyun";
myArray["1"] = "Huairou";
// myArray = ['Miyun', 'Huairou']

Finally, you can set the index signature to read-only, which prevents assigning values to the index.

interface ReadonlyStringArray {
  readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!

Class type

TypeScript can use interfaces to explicitly force a class to conform to a definition.

Here, we use implements to define a member type that a class must implement. Of course, you can also formulate only one rule for an interface and splice the interface to refine the definition of the interface.

interface FamilyRespons {
  cook(doing: string): void;
  clean(doing: string): void;
}
interface Teach {
  teach(type: string): void;
}
interface Study {
  study(time: num): void;
}

class Father implements FamilyRespons, Teach {
  cook(doing: string): void {}
  clean(doing: string): void {}
  teach(type: string): void {}
}

class Children implements FamilyRespons, Study {
  cook(doing: string): void {}
  clean(doing: string): void {}
  study(time: num): void {}
}

Interface inheritance

Like classes, interfaces can inherit from each other, and can be more flexibly divided into reusable modules, which are also used   extends keyword, and an interface can inherit multiple interfaces to create a composite interface of multiple interfaces.

interface Background {
  color: string;
}

interface Content {
  width: number;
}

interface BoxStyle extends Background, Content {
  borderWidth: number;
}

let boxCss: BoxStyle = {
  color: "red",
  width: 100,
  borderWidth: 1,
};

Part 08 - TypeScript generics

Definition of generics

Generics means that when we define functions, interfaces, etc., we do not specify their types, but specify the characteristics of types when we use them.

For example, when we declare a function, we do not declare the type of parameters. When we use a call, we define the type passed in through the need to pass parameters.

function identity<T>(arg: T): T {
  return arg;
}
let output = identity<string>("myString"); // function identity<string>(arg: string): string

In general, we represent type variables by < T >. T helps us modify the type of input specified for the user.
After we define the generic function, we can use it by passing in the type we want in < >. For example: < string > < number >, etc

Generic variable

When we create a generic function, you must use it as a general type in the function body.

For example, the following is wrong

function loggingIdentity<T>(arg: T): T {
  console.log(arg.length);  // Error: property 'length' does not exist on type'T '
  return arg;
}

When you are an arbitrary type, you may pass in number, so there is no length attribute, so we can define this generic type by creating an array.

function loggingIdentity<T>(arg: T[]): T[] {
  console.log(arg.length);  // Success
  return arg;
}

When you define an array and the value inside the array is generic, the length method will be used reasonably.

generic interface

Firstly, the types of generic functions are no different from those of non generic functions, and interfaces can also be defined through generics, including generic types through < >.

interface TestInterface<T> {
  <T>(arg: T): T;
}

function FunctionInterface<T>(arg: T): T {
  return arg;
}

let myIdentity: TestInterface<number> = FunctionInterface;

Generic class

Generic classes look like generic interfaces. Generic classes are also used  <> Enclose the generic type, followed by the class name.

class TestClasses<T> {
  value?: T;
  add?: (x: T, y: T) => T;
}

let doSomeThing = new TestClasses<string>();

doSomeThing.value = 'creatString';
doSomeThing.add = (x, y) => x + y;

Generic constraints

Take the generic variable as an example. You want to access the length attribute of Arg inside the function body, but because the type of arg is uncertain, we need to restrict the type of Arg to include at least this attribute.

interface Length {
  length: number;
}

function loggingIdentity<T extends Length>(arg: T): T {
  console.log(arg.length); // Success
  return arg;
}
loggingIdentity(10); // Error has no length attribute
loggingIdentity({ length: 10 });

When T inherits the generic length, the parameter must contain the necessary attributes, so the use of length naturally becomes reasonable.

Part 09 - TypeScript declaration merge

Merge interface

When two interfaces with the same name are merged, the members of both sides are actually placed in an interface with the same name.

interface Box {
  height: number;
  width: number;
}

interface Box {
  scale: number;
}

let box: Box = {height: 5, width: 6, scale: 10};

At the same time, it should be noted that when the interface   A and subsequent interfaces   A when merging, the following interfaces have higher priority. That is, later interfaces will be overloaded in the front position.

interface Box {
  scale: number;
  height: number;
  width: number;
}

ending

Because at present, I only study according to some contents of version 3.1 of the Chinese official website. Therefore, the new features after 3.1 have not been carefully studied and output.

After that, I will read carefully according to the updated content of the typeScript official website version, and continue to output the content I learned. As a newcomer to the blog, I hope the bosses can provide more suggestions to help me improve better. If you think it's not good, I hope you guys spray it gently! Thank you so much!

Tags: Javascript ECMAScript TypeScript Ajax ts

Posted on Mon, 29 Nov 2021 14:23:13 -0500 by DoctorWho