Basic types and object types

Base types: number, string, null, undefined, symbol, Boolean, void

const num: number = 123;
const teacherName: string = 'Dell';
Copy the code

Object types: {}, [], Class, function

const teacher: {
  name: string;
  age: number;
} = {
  name: 'Dell'.age: 18};const numbers: number[] = [1.2.3];

class Person {}
const dell: Person = new Person();

const getTotal: () = > number = () = > {
  return 123;
};

const func1: (str: string) = > number = (str) = > {
  return parseInt(str, 10);
};

const func2 = (str: string) :number= > {
  return parseInt(str, 10);
};
Copy the code

Type annotations and type inference

// Type annotation: Let's tell TS what type a variable is
let count1: number;
count1 = 123;

// Type inference: TS automatically attempts to analyze the types of variables
let count2 = 123;

If TS can automatically analyze variable types, we don't need to do anything
const num1 = 1;
const num2 = 2;
const total = num1 + num2;

// If TS cannot parse the variable type, we need to use type annotations
function getTotal2(num1: number, num2: number) {
  return num1 + num2;
}

const total = getTotal2(1.2);
Copy the code

A type associated with a function

Void, never

As in JS, there are three main types of function definitions
function hello() {}
const hello1 = function () {}
const hello2 = () = > {}

// The last number can be inferred by type inference
// But to be on the safe side, it is better to write. Because it's possible to make a code mistake while doing logic.
function add(first: number, second: number) :number {
  return first + second
}

// Common function types include void, never, etc
function sayHello() :void {
  console.log("hello")}// never: used when the function never completes or an exception is thrown
function errorEmitter() :never {
  throw new Error(a)// while(true) {}
  console.log("123")}// Destruct type annotations
function add({ first, second }: { first: number; second: number }) :number {
  return first + second
}
const total = add({ first: 1.second: 2 })

// Destruct a variable
function getNumber({ first }: { first: number }) :number {
  return first
}
Copy the code

Other situations

Any: Indicates any type

// Others: Date type etc
const data = new Date(a)// Other cases: for example, when using json. parse and other functions, there is no type inference. Use type annotations
interface Person {
  name: "string"
}
const rawData = '{"name":"Dell"}'
const newData = JSON.parse(rawData) // Type inference cannot be used. NewDate is of type any
const newData2: Person = JSON.parse(rawData) // newDate2 is of type Person
Copy the code

Types of assertions

Sometimes you’ll find that you know more about a value than TypeScript does. Usually this happens when you clearly know that an entity has a more exact type than its existing type. Type assertions are a way of telling the compiler, “Trust me, I know what I’m doing.” Type assertion is like conversion in other languages, but without special data checking and deconstruction. It has no run-time impact, only at compile time. TypeScript assumes that you have done the necessary checking.

Type assertions come in two forms. The first is the Angle bracket syntax:

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

The other is as syntax :(when using JSX in TypeScript, only as syntax assertions are allowed)

let someValue2: any = "this is a string"
let strLength2: number = (someValue as string).length
Copy the code

Type – Type alias

A type alias is also a type that uses a single word to represent a potentially complex type declaration, represented by the keyword type.

Example:

type S = string
let a: S = 'a'
Copy the code

Here we use S as the alias for string, using the same method as string.

An alias can represent any type, not just a basic type. Example:

type SA = string[] // represents an array of strings
type Handler = (x: string) = > void // represents the function
type I = {
  // Represents the interface
  name: string
  value: number
}
class C {
  name: string = 'a'
  value: number = 0
}
type D = C / / on behalf of the class
Copy the code

Interface – interface

interface Person {
  name: string;
  readonlyage? :number;
}

const getPersonName = (person: Person): void= > {
  console.log(person.name);
};
const setPersonName = (person: Person, name: string) :void= > {
  person.name = name;
};

const person = {
  name: 'Jonas'.age: 22}; getPersonName(person); setPersonName(person,'Mike');
getPersonName(person);
Copy the code

In addition, interfaces can be inherited just like classes.

Using variables, you can add attributes to person that are not defined in the interface:

interface Person {
  name: string;
  readonlyage? :number;
}

const person = {
  name: 'Jonas'.age: 22.sex: 'male'
};

getPersonName(person);
Copy the code

However, if you use the literal method, an error is reported because literals are strictly checked.

getPersonName({
  name: 'Jonas'.age: 22.sex: 'male' / / an error
});
Copy the code

Class – class

A little different from JS, for example, the following example must define the type of name.

class Person {
  name: string;
  eat() {
    return `The ${this.name} is eating something`}}const jonas = new Person();
jonas.name = 'Jonas';
console.log(jonas.eat());
Copy the code

Access type

  • Public: allowed to be used inside and outside a class
  • Private: Allowed to be used within a class
  • Protected: Allowed to be used within classes and in inherited subclasses

The constructor – constructor

Constructor is performed automatically when instantiated.

class Person {
  name: string;
  constructor(name: string) {
    this.name = name; // this.name refers to the name defined in the class, and the name to the right of the equals sign is the name passed in by the constructor
  }
  eat() {
    return `The ${this.name} is eating something`}}const jonas = new Person('Jonas');
console.log(jonas.eat());
Copy the code

Constructor parameters can also be simplified:

class Person {
  // The traditional way
  // public name: string;
  // constructor(name: string) {
  // this.name = name;
  // }
  // Simplify
  constructor(public name: string){}eat() {
    return `The ${this.name} is eating something`; }}const jonas = new Person('Jonas');
Copy the code

inheritance

class Student extends Person {
  study() {
    return `The ${this.name} is studing`; }}const mike = new Student('Mike');
console.log(mike.study());
Copy the code

If a subclass has a constructor, we need to call the parent class’s constructor first:

class Student extends Person {
  constructor(public age: number) {
    super('Dell'); }}const dell = new Student(29);

console.log(dell.age); / / 29
console.log(dell.name); // Dell
Copy the code

Super () is called in the constructor of a subclass even if the parent class has no constructor.

Getter and setter

class Person {
  constructor(private name: string) {}
  get getName() {
    return this.name + ' the boy'; // We can do some protection here}}const jonas = new Person('Jonas');
console.log(jonas.getName); // Jonas the boy, getName
Copy the code

Generally used like this:

class Person {
  constructor(private _name: string) {}
  get name() {
    return this._name + ' the boy';
  }
  set name(name: string) {
    const realName = name.split(' ') [0];
    this._name = realName; }}const person = new Person('Jonas');
console.log(person.name); // Jonas the boy
person.name = 'Mike';
console.log(person.name); // Mike the boy
Copy the code

To design read-only, you can use the readonly modifier in addition to setting getters but not setters.

class Person {
  public readonly name: string;
  constructor(name: string) {
    this.name = name; }}Copy the code

A comprehensive example: the singleton pattern

The singleton pattern is that there can only be one instance of a class.

// Singleton mode
class Demo {
  private static instance: Demo;
  private constructor(public name: string) {} // Make the constructor private so that it cannot be instantiated with new outside the class

  static getInstance(name: string) { // Static is hanging directly on a class, not on an instance of the class
    if (!this.instance) {
      this.instance = new Demo(name);
    }
    return this.instance; }}const demo1 = Demo.getInstance('Jonas');
const demo2 = Demo.getInstance('Mike');
console.log(demo1.name); // Jonas
console.log(demo2.name); // Jonas
Copy the code

Other types of

There are: union, cross, generics, literal types, etc.

The joint type

It can be any of several types:

let temp: number | string = 123
temp = "456"
Copy the code

Cross type

Is a new type that combines several types and has attributes for all types:

interface IName {
  name: string;
}
type IPerson = IName & { age: number };
let person: IPerson = { name: '123'.age: 123 };
Copy the code

literal

const str: 'name' = 'name';
const number: 1 = 1;
type Directions = 'Up' | 'Down' | 'Left' | 'Right';
let toWhere: Directions = 'Left';
Copy the code

The generic

The type is not defined until it is used. Let’s say we define a function that returns a value of the same type as the value passed in. This is where we can use generics. Add a generic T for the function, using the type of the value passed in by T.

function echo<T> (arg: T) :T {
  return arg;
}
Copy the code

Generics can be used in two ways:

The first is to pass in all the arguments, including the type arguments:

const result1 = echo<string> ('123'); // string
const result2 = echo<number> (123); // number
Copy the code

Here we explicitly specify that T is a string and is passed to the function as an argument, enclosed in <> instead of ().

The second method is more common. Makes use of type corollaries — that is, the compiler automatically helps us determine the type of T based on the arguments passed in:

const result1 = echo('123'); // string
const result2 = echo(123); // number
Copy the code

Note that we do not need to use Angle brackets <> to pass in the type explicitly; The compiler can look at the value of myString and set T to its type. Type inference helps us keep our code lean and readable. If the compiler cannot automatically infer the type, it can only pass in the type of T explicitly as above, which is possible in some complicated cases.

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

Constraints of generic

In the previous echo function, if we wanted to print the length of the ARG at the same time. We would probably do something like this:

function echo<T> (arg: T) :T {
  console.log(arg.length);
  return arg;
}
Copy the code

The program will report an error because the type passed in does not necessarily have the length attribute. If we operate on an array of type T instead of T, then the length property will not be reported:

function echo<T> (arg: T[]) :T[] {
  console.log(arg.length);
  return arg;
}
Copy the code

But in addition to arrays, there are many types that have the Length attribute. So how to solve it? You need to use generic constraints. We define an excuse with the length property and then use the extends,

interface hasLength {
  length: number
}

function echo<T extends hasLength> (arg: T) :T {
  console.log(arg.length);
  return arg;
}
Copy the code

Thus, only types with the length attribute can be passed in:

const str = echo('string');
const obj = echo({ length: 100.width: 200 });
const arr = echo([1.2.3]);
const num = echo(123); / / an error
Copy the code

Generic constraints can be applied not only to functions, but also to interfaces and classes.

Built-in types

// global object
const a: Array<number> = [1.2.3];
const date = new Date(a); date.getTime();const reg = /abc/;
reg.test('abc');

// built-in object
Math.pow(2.2);

// DOM and BOM
let body = document.body;
let allLis = document.querySelectorAll('li');
allLis.keys();

document.addEventListener('click'.(e) = > {
  e.preventDefault();
});
Copy the code

Utility Types

Pertial: All attributes are optional with Partial.

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

let viking: Person = { name: 'Viking'.age: 20 };
type personPartial = Partial<Person>;
let viking2: personPartial = { name: 'Viking' };
Copy the code

Omit: Omit certain attributes.

type personOmit = Omit<Person, 'name'>;
let viking3: personOmit = { age: 20 };
Copy the code

Reference article: juejin.cn/post/694931… www.tslang.cn/docs/handbo…