Typescript development and learning summary

Typescript development and learning summary, If you evaluate the major breakthroughs of the front-end in the last five years, you will Typescriptdefinitely be among them. Typescript development and learning summary.

The major technical forums and interviews at major companies all believe that it Typescriptshould be a must-have skill for the front-end. As a news blocker, I was ridiculed by my colleagues as “Neolithic code farmers”, and finally got on the train at the end of 2019 Typescript. I compiled a lot of notes and code snippets during the year of use, and it took some time to organize them into the following.

Typescript development and learning summary
Typescript development and learning summary

Typescript development and learning summary

This article is not a tutorial. The main purpose is to share my personal Typescriptunderstanding and code snippets during the one-year development period. Therefore, the content of the article mainly revolves around the research and understanding of certain features. I also hope to help some Typescriptfriends who are also learning to use , and hope to point out any errors or omissions. Typescript development and learning summary.

Basic data type

JavascriptThere are 6 basic types: StringNumberBooleanNullUndefinedSymbol, corresponding Typescriptto the 6 types of declarations: stringnumberbooleannullundefinedsymbol.

Several rules apply to the type declaration of basic data types:

  1. TypescriptThe code will be statically type checked at compile time. In most cases, implicit conversion is not supported and an let yep: boolean = 1error will be reported.
  2. TypescriptThe first letter of the basic type declaration in is not case-sensitive, which is let num: number = 1equivalent to let num: Number = 1, but lowercase is recommended
  3. TypescriptAllows variables to have multiple types (ie union types), just by |connecting, such as let yep: number | boolean = 1, but it is not recommended to do so
  4. Type declaration does not occupy variables, so it let boolean: boolean = trueis allowed, but it is not recommended
  5. By default, in addition neverTypescriptcan put other types of variable declarations (including reference data type) is assigned nullundefinedvoid 0without error. But this is definitely wrong, it is recommended tsconfig.jsonto "strictNullChecks": trueblock this situation in the settings
  6. For basic type , it unknownand anythe end result is the same
// String type declaration, single quotes/double quotes do not affect type inference
let str: string = 'Hello World';

// Number type declaration
let num: number = 120;
// These values are also legal numeric types
let nan: number = NaN;
let max: number = Infinity;
let min: number = -Infinity;

// Boolean type declaration
let not: boolean = false;
// Typescript only checks the result,! 0 finally gets true, so no error will be reported
let yep: boolean = !0;

// symbol type declaration
let key: symbol = Symbol('key');

// Never type can not be assigned
// excute console.log(never === undefined),result is true
let never: never;
// But even if never === undefined, the assignment logic will still report an error
never = undefined;

// Except for never, when strictNullChecks is not enabled, other types of variables are assigned null/undefined/void 0 and no error is reported
let always: boolean = true;
let isNull: null =  null;
// No error
always = null;
isNull = undefined;

Typescript development and learning summary

Reference data type

JavascriptThere are many types of reference data, such as ArrayObjectFunctionDateRegexpand so on, and the type of foundation is not the same place is, Typescriptin some places and not simply and Javascriptdirectly correspond to the results of the implementation part of people scratching their heads.

In terms of writing rules, in addition to the Objectother, Typescriptthe first letter of the reference data type declaration must be capitalized. If an let list: array<number> = [1]error occurs, it must be written let list: Array<number> = [1]. The reason is that these reference data types are essentially constructors, and Typescriptthe bottom layer will list instanceof Arrayperform type comparisons through similar logic.

One of the more interesting points is that among all data types, it Arrayis the only generic type, and it is also the only two different ways of writing: Array<T>and T[].

Type declarations related to arrays include tuples Tuple. The difference with arrays is mainly reflected in the fact that the length of tuples is fixed and known. Therefore, the usage scenario is also very clear, suitable for use in places with fixed standards/parameters/configurations, such as latitude and longitude coordinates, screen resolution, etc.

//
let arr1: Array<number> = [1]
let arr2: number[] = [2]

//When strictNullChecks is not enabled, assign null/undefined/void 0 to not report an error
let arr3: number[] = null
// No errors will be reported during compilation, and errors will be reported during runtime
arr3.push(1)

// Tuple type
// Coordinate representation
let coordiate: [ number, number ] = [114.256429,22.724147]

// Other reference data types
let date: Date = new Date()
let pattern: Regexp = /\w/gi

// Simple use of type declaration in functions
// How to write function expressions
function fullName(firstName: string, lastName: string): string {
  return firstName + ' ' + lastName
}
// Function declarative writing
const sayHello = (fullName: string): void => alert(`Hello, ${ fullName }`)

// When you don’t know the return value of the function, but don’t want to use any/unknown, you can try this type of declaration, but it is not recommended
const sayHey: Function = (fullName: string) => alert(`Hey, ${ fullName }`)

Typescript development and learning summary

In Typescriptthe statement on the type of object There are three forms: Objectobject{}, I started to think that Objectwould be like Arrayis a generic type, however, been tested and found not only not a generic, there is a first letter lowercase objectObjectobject{}three of the The results of the implementation are completely different.

  1. To Objectas a type declaration, the variable value may be any value, such as strings / digital / array / function or the like, but if the variable value is not an object, it can not use the unique method of variable value, such as let list: Object = []not being given, but the implementation list.push(1)will be given . The reasons for this is because Javascriptwhen the not found properties / methods in the prototype chain for the current object will look up the object layer, and Object.prototypeis the end of the chain to find all the objects of the prototype, so also Typescriptwill the type Declared that Objectno error will be reported, but non-object properties/methods cannot be used
  2. To objectas type declarations, variable values can only be an object, other values error. It is worth noting that the objectdeclared object cannot access/add any properties/methods on the object. The actual effect is similar to Object.create(null)the empty object created by it. For the time being, I don’t know the reason for this design.
  3. {}In fact, anonymous form type, and therefore support through &|the operator of the type declaration be extended (ie, cross-type and union type)
// Assigning to a number will not report an error
let one: Object = 1
// It is also assigned to the array, but the push method of the array cannot be used
let arr: Object = []
// error
arr.push(1)

// Assignment will report an error
let two: object = 2

// When object is declared as a type, no error will be reported when assigning to the object
let obj1: object = {}
let obj2: object = { name: 'znlive.com' } 
let Obj3: Object = {}

// Will report an error
obj1.name = 'znlive.com'
obj1.toString()
obj2.name

// No error
Obj3.name = 'znlive.com'
Obj3.toString()

// {} Equivalent to the anonymous form of type
type UserType = { name: string; }

let user: UserType = { name: 'znlive.com' }
let data: { name: string; } = { name: 'znilve.com' }

Typescript development and learning summary

Cross type and joint type

Mentioned above, Typescriptsupported by &|the operator of the type declaration be extended with &a plurality of types of cross linked type, with a |plurality of types of joint coupled type. Typescript development and learning summary

The main difference between the two types of reflected mainly in the United do combined type, such as Form4Type, ; Form6Typeand is seeking the same type of cross rejection, such as Form3TypeForm5Type. You can also use mathematical collections and unions to understand the union type and the intersection type, respectively.

type Form1Type = { name: string; } & { gender: number; }
// equal type Form1Type = { name: string; gender: number; }
type Form2Type = { name: string; } | { gender: number; }
// equal type Form2Type = { name?: string; gender?: number; }

let form1: Form1Type = { name: 'znlive.com' } // Prompt that the gender parameter is missing
let form2: Form2Type = { name: 'znlive.com' } // Verified


type Form3Type = { name: string; } & { name?: string; gender: number; }
// equal type Form3Type = { name: string; gender: number; }
type Form4Type = { name: string; } | { name?: string; gender: number; }
// equal type Form4Type = { name?: string; gender: number; }

let form3: Form3Type = { gender: 1 } // tips lost name parms
let form4: Form4Type = { gender: 1 } // verified


type Form5Type = { name: string; } & { name?: number; gender: number; }
// equal type Form5Type = { name: never; gender: number; }
type Form6Type = { name: string; } | { name?: number; gender: number; }
// equal type Form6Type = { name?: string | number; gender: number; }

let form5: Form5Type = { name: 'Jack', gender: 1 } // Prompt that the type of name is never and cannot be assigned
let form6: Form6Type = { name: 'Rick', gender: 1 } // verified

Typescript development and learning summary

The above code snippets generally only appear in the interview questions. If this kind of code appears in the real project code, it is estimated that it will be directly criticized during the code review. Typescript development and learning summary

However, it is not without practical scenarios. Take Apple’s educational discounts as an example: suppose you need 5000 yuan to buy Apple 12 at the original price; if you buy through educational discounts, you can enjoy a certain discount (such as a 20% discount), but you need to provide a student card or It is a teacher’s card. After the product manager’s sorting out, it may become a demand document: no other materials are required for purchase at the original price. If you want to enjoy the educational discount, you need to submit your personal information and a scanned copy of your student ID/teacher ID.

// Original price purchase
type StandardPricing = {
  mode: 'standard';
}
// Education discount purchase requires the purchaser's name and relevant documents
type EducationPricing = {
  mode: 'education';
  buyer_name: string;
  sic_or_tic: string;
}
// Pass & and | Combine Type
type buyiPhone12 = { price: number; } & ( StandardPricing | EducationPricing )


let standard: buyiPhone12 = { mode: 'standard', price: 5000 }
let education: buyiPhone12 = { mode: 'education', price: 4000, buyer_name: 'Jack', sic_or_tic: 'Certificate' }

Typescript development and learning summary

Type and Interface

At the beginning of my study , I Typescriptsaw interfacethat the first thing I thought of was JavaJavaIt interfaceis an abstract class that separates the definition of the function from the specific implementation, so that different people can interfacecooperate with each other, similar to the role of requirements documents in development.

// znlive defined three functions of the user center: login, register, and retrieve password
interface UserCenterDao {
  void userLogin();
  void userRegister();
  void userResetPassword();
}

// rick develops the function of the user center and prompts that three functions need to be implemented
class UserCenter implements UserCenterDao {
  public void userLogin() {};
  public void userRegister() {};
  public void userResetPassword() {};
}

Typescript development and learning summary

TypescriptFor the interfacedefinition is similar, abstract variables are declared series / method, and then by the specific code to achieve. Typescript development and learning summary

interfaceThe overall effect with typethe effect of the statement is very similar, even exclusively interfaceinheritance extendstypecan also &|operator implemented, nor are independent therebetween, each call can be performed.

Therefore, in the usual actual development, you don’t have to be too entangled in using typeor interfacemaking type declarations, especially when entangled type.

// Use interface to define the basic attributes of a student as name, gender, school, grade, and class
interface Student {
  name: string;
  gender: 'male' | 'Female';
  school: string;
  grade: string | number;
  class: number;
}

// Use interface to inherit the basic attributes of students
// And additionally define the standard for students to comply with school rules, be helpful, and the top three in the class
interface MeritStudent extends Student {
  toeTheLine: boolean;
  helpingOther: boolean;
  topThreeInClass: boolean;
}

// The type declared by the interface can be declared to the new declaration by type
type StudentType = Student

// Although interface cannot directly use the type declared by type, it can be used indirectly through inheritance
interface CollageStudent extends StudentType {}

// Then declare the corresponding logic to implement
let xiaoming: Student = {
  name: 'xiaoming',
  gender: 'male',
  school: 'Alis Kindergarten',
  grade: 'Big class',
  class: 1
}

let xiaowang: MeritStudent = {
  name: 'mark',
  gender: 'male',
  school: 'Alis Kindergarten',
  grade: 'Big class',
  class: 1,
  toeTheLine: true,
  helpingOther: true,
  topThreeInClass: true
}

let xiaohong: StudentType = {
  name: 'Rick',
  gender: 'Female',
  school: 'Linda Primary School',
  grade: 1,
  class: 1
}

Typescript development and learning summary

Speaking typeand interfacehas a very classic Typescriptface questions: typeand interfacethe difference between where? Typescript development and learning summary

Let me talk about personal feelings first. I personally feel that the difference between typeand interfaceis mainly in semantics. typeThe definition in the official document is a type alias, and interfacethe definition is an interface. Typescript development and learning summary

The following code can clearly reflect the semantic difference between the two. In fact , the difference between the two in terms of syntax is not that big. Typescript development and learning summary

// type can define aliases for types
type StudentName = string

// Interface can define an abstract class for students like Java
interface StudentInterface {
  addRecord: (subject: string, score: number, term: string) => void
}

// Equivalent to let name: string ='Jack'
let name: StudentName = 'Jack'


// The constructor CollageStudent gets the declaration of the abstract class StudentInterface
class CollageStudent implements StudentInterface {

  public record = []

  addRecord(subject, score, term) {
    this.record.push({ subject, score, term })
  }
}

// Type actually defines a similar type declaration structure, but it is not an abstract class semantically
type TeacherType = {
  subject: Array<string>
}
// The constructor can also get the type declared by the type, which is grammatically achievable
// But from the perspective of semantics and norms, it is not recommended to write this way
class CollageTeacher implements TeacherType {

  subject: ['Mathematics','sports']
}

Typescript development and learning summary

As for the standard answer, the official document ( click here ) gives the specific grammatical differences between the two. Typescript development and learning summary

Typescript development and learning summary
Typescript development and learning summary

Generic

What is generic? Simply put, generics are variables in type declarations . An unrelated but well-understood example: Typescript development and learning summary

JavascriptWhen executing let num = 1this code, Javascriptthe compiler will execute the code from right to left. Before the code is executed, the compiler does not know numthe data type of the variable . After the execution, the compiler knows the numdata type of the variable Number. Typescript development and learning summary

This also happens to be the core of generics: you don’t know what type it is before compilation, you will know it after compilation . Typescript development and learning summary.

// The writing form of generic type is <T>, you can pass <T = ?> as generic type with default value
// How to write function expressions
function typeOf<T>(arg: T): string {
    return Object.prototype.toString.call(arg).replace(/\[object (\w+)\]/, '$1').toLowerCase()
}

// equal typeOf<string>('Hello World')
typeOf('Hello World')
// equal typeOf<number>(123456)
typeOf(123456)

// Function declarative writing
const size = <T>(args: Array<T>): number => args.length

// Equivalent to size<number>([ 1, 2, 3 ])
size([ 1, 2, 3 ])

Typescript development and learning summary

Although the above code is relatively simple, it is enough to see the flexibility of generics, which can make components more reusable, but it may still be difficult to understand the usefulness of generics in actual projects.

Below is the code snippet I used in the actual project. The code is a bit long but the logic is not complicated. The code is mainly used to request the hooks of the back-end interface. Two generics are defined : RequestConfigand AxiosResponse, which are used to define the structure of request parameters and return parameters respectively. The code also uses generic nesting Promise<AxiosResponse<T>>to facilitate the duplication of multi-layer structures. use. Typescript development and learning summary

import axios, { AxiosRequestConfig } from 'axios'

// Structure of request parameters
interface RequestConfig<P> {
  url: string;
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  data: P;
}

// Return the structure of the parameters
interface AxiosResponse<T> {
  code: number;
  message?: string;
  data: T;
}

const $axios = axios.create({ baseURL: 'https://demo.com' })

// Two generic types T and P are declared
// T-the generic type of the return parameter, the default value is void, no need to pass the type declaration when there is no return parameter
// P-The generic type of the request parameter, the default value is void, no type declaration is required when there is no request parameter
// Generics support nesting, such as Promise<AxiosResponse<T>> means that the return value of AxiosResponse<T> is in Promise
const useRequest = async <T = void, P = void>(requestConfig: RequestConfig<P>): Promise<AxiosResponse<T>> => {
  
  const axiosConfig: AxiosRequestConfig = {

    url: requestConfig.url,
    data: requestConfig.data || {},
    method: requestConfig.method || 'GET'
  }

  try {
    // Data is the expected return parameter and the expected return parameter
    const { data: response } = await $axios(axiosConfig)
    
    // Error response
    if( response.code !== 200 ) {

      return Promise.reject(response)
    }

    return Promise.resolve(response)
  } catch(e) {
    // Error response
    return Promise.reject(e)
  }
}

(async () => {

  interface RequestInterface {
    date: string;
  }
  interface ResponseInterface {
    weather: number;
  }

  // Used when there are no parameters, no need to constrain generics
  await useRequest({ url: 'api/connect' })
  // Use when there are parameters to improve code quality through generic constraints
  const { weather } = await useRequest<RequestInterface, ResponseInterface>({
    url: 'api/weather',
    data: { date: '2021-02-31' }
  })
})()

Typescript development and learning summary

In addition, Typescripttype declarations are allowed to call themselves. This feature can be used to achieve requirements similar to a tree structure. The more common one is the navigation menu of the management system. Typescript development and learning summary

// Typescript supports calling itself recursively
type TreeType = {
  label: string;
  value: string | number;
  children?: Array<TreeType>
}
// So you can use this feature to achieve a tree structure
let tree: Array<TreeType> = [
  
  { label: 'Home', value: 1, children: [
    { label: 'dash board', value: '1-1' },
    { label: 'Workbench', value: '1-2' },
  ] },
  { label: 'Schedule management', value: 2, children: [
    { label: 'Progress setting', value: '2-1' },
    { label: 'Operation record', value: '2-2' },
  ] },
]

Typescript development and learning summary

Leave a Comment