Foreword: blogger 2020.3 formally enter the front end, target senior front end engineer, experience is still shallow, if the content of the article is wrong, welcome to correct.

One: the type system of programming language

1. Strongly typed versus weakly typed languages

Language type of strong and weak points, the industry and there is no authoritative comparison concept, so there are a lot of different views on the Internet. But what most of this means is that strongly typed languages have stronger type constraints, whereas weakly typed languages have few constraints.

The following personal understanding of strong and weak types after the course:

  • Strongly typed languages: Program runtime variable types do not allow arbitrary implicit type conversions (type safety).
  • Weakly typed language: program runtime variable types allow arbitrary implicit type conversions (type insecurity).

The easiest code to understand:

// Strongly typed languages: Java, Python, etc
100 - '50' // Report syntax error

// Weakly typed language: javaScript
100 - '50' / / 50
Copy the code

Statically typed versus dynamically typed languages

The following personal understanding of static typing versus dynamic typing after the course:

Static typing: after a variable’s type is declared during program development, it is not allowed to be modified (the type is checked at compile time). Dynamic typing: Variable types can change at any time after they are declared during program development (runtime check type).

The easiest code to understand:

// Statically typed language: Java
int a = 100;
a = '100';  // Report syntax error

// Dynamically typed language :javascript
var a = 100;
a = '100';  // typeof(a) outputs 'string'
Copy the code

3. Classification of major programming languages

Two: Javascript type system defects

1. Poor program robustness

The JavaScript language itself is a dynamically weakly typed interpreted language. Before getting into the details of its type defects, let’s take a look at a few examples of common JavaScript type errors in everyday development:

let fn, name, age = 10, inputAge = '1';
fn()			// Undefined cannot be called as a function object
const fn1 = fn; // Potential error: Fn1 is not a method

age = age + inputAge;// The operation is not correct, but the age calculation is not correct, and the conversion of type to string is also a potential error
<p> {name} </p> 	// Not running correctly, user sees undefined
Copy the code

From the code above we can tell, we write a JavaScript program usually happen a lot of errors in fact is a type error, we found these errors and the debugging solve it spent a lot of time, however, still there are many types of potential errors in the program have not found, the following thinking about a wave of the error reason:

  • JavaScript is dynamically typed: it means that during program development, the source code developed by the developer is handed to the interpreter without type checking.

  • JavaScript is weakly typed: this means that when a program encounters a type problem caused by the developer at runtime, it takes it upon itself to perform implicit type conversions, reporting an error if the conversion fails, and returning the result of the operation if the conversion succeeds (sometimes not the desired result, i.e., the execution is not accurate).

  • JavaScript is both dynamically typed and weakly typed, which makes JavaScript programs vulnerable to type errors, hidden potential errors, and inaccurate program execution when errors are not recognized as errors.

2. Original solution

Programs are prone to type errors, hidden potential errors, and errors that are not recognized as errors and run inaccurately. A good developer would never recognize these things. Therefore, we often add some type judgment codes in our daily JavaScript development to avoid the occurrence of errors.

/ / in case 1
const obj = {};
// obj.foo();	// error
if(obj.foo){	// error proofing
	obj.foo();
} else {
  // xxx  
}

/ / case 2
function sum (a, b) {
   return a + b
}
function sum (a, b) {	// error proofing
    if(! (typeOf(a)==='int' && typeOf(b)=== 'int')) {throw new TypeError('arguments should be number');
    } 
   return a + b
}
Copy the code

When writing JavaScript, we often write this code intentionally to avoid or solve type errors, but let’s examine the disadvantages of solving type problems this way:

  • Higher development costs: In addition to writing the core logic of the code, developers have to spend more time and effort writing code that avoids type problems, especially when encapsulation is used by others.
  • Only part of the problem: You can’t make a type judgment every time a variable is used, so this solution only solves part of the problem.
  • Large amount of type determination code: This solution requires a large amount of type determination code to be written in the program to avoid errors, which can easily lead to large code, hidden core business code, code is not clear, etc.
  • Performance issues: The need to run this type determination logic code at run time definitely consumes more run time.

The above solution is ugly, but it’s the implicit solution we use to avoid typing problems when writing JavaScript code.

After talking about so many defects in JavaScript’s type system, and then talking about the original solution, there is a sudden feeling that programming in JavaScript sucks. No wonder so many people call JavaScript a clown language, embarrassing!

In fact, so many types of problems occurred during the running of JavaScript are caused by the fact that JavaScript itself has no constraints on variable types, and type checking cannot be carried out in the development stage, which makes the JavaScript code written by developers prone to programming errors.

Learning from the practices of other languages, we might think that type constraints at development time would be an alternative to type judgments for JavaScript typing errors. In implementation, there are two main solutions to this idea: Flow and Typescript. They are all type constraints and type checking realized by adding type declaration on the source code, and then type problems solved by compiling and getting a strict type of JavaScript code to the JavaScript interpreter. This mainly involves three processes: development, checking and compilation:

  • Development phase: The development phase adds appropriate type declarations to variables according to the rules.
  • Check phase: Use the check tool to check the match according to the variable type declaration and variable value. It is divided into three kinds: check at code time (code prompt), check after code and check at compile time.
  • Compile phase: Use the compile tool to remove type declarations for variables and get a tightly typed JavaScript code.

3.Flow solutions

Flow is a static type checking tool for JavaScript. It defines a set of type constraints and checking rules. After passing the check, it can compile a set of JavaScript code with strict type and no Flow type declaration to solve JavaScript type problems. Here’s a brief description of how Flow solves JavaScript typing problems in three stages: development, review, and compile. See the official documentation for details.

1): Add type declarations during development

Adding a type declaration involves three parts: type annotations in your own code, type annotations in the context API (Window/Node), and type annotations in third-party libraries (introduced lib). When there is a lack of type annotations in API and third-party library files, we usually solve this problem by introducing type declaration files.

Here is an example of adding a type declaration to your code:

// @flow
// test.js
function sum(m: number, n: number) :number {
	return m + n
}
Copy the code

2): Type matching is carried out in the inspection stage

Type check can be divided into three types: code-time check, post-code check, and compile-time check. The code-time check tool is usually a plug-in provided by the IDE, and the post-code and compile-time check is usually provided by the official check tool.

Check tools for Flow encoding are not discussed here. The following is a brief description of the workflow of check after Flow encoding:

  • Install the check tool flow-bin
yarn add flow-bin --dev
Copy the code
  • Write to check the configuration information:.flowConifg
#Generate the. Flowconifg configuration file, where you can configure check source, check rule, check output position, and so on
yarn flow init
Copy the code
  • Read the configuration to perform the check
yarn flow
Copy the code
  • The console outputs the check result
  • Modify type errors in code according to check reports

3): Type declarations are removed at compile time

Type annotations in the Flow source code do not conform to JavaScript syntax, and throwing them directly to the JavaScript interpreter will cause errors, so we need to compile the source code to remove the type declaration and get JavaScript code that can be executed by the JavaScript interpreter. Resolve JavaScript type issues.

There are two ways to remove Flow annotations from JavaScript files:

  • Use the flow-remove-types library to remove these types
#The installation
yarn add flow-remove-types --dev
#Remove: command argument, compile input code position, compile output code position
yarn flow-remove-types src -d dist
Copy the code
  • Remove this using the Babel plugin @babel/preset-flow
#The installation
npm install --save-dev @babel/core @babel/cli @babel/preset-flow
#Configuration: the.babelrc file configures the preset-flow plug-in
{
  "presets": ["@babel/preset-flow"]
}
#Conversion: command arguments, where input code is compiled, where output code is compiled
yarn babel src -d dist
Copy the code

The ultimate Typescript solution

Like Flow, TypeScript is a type checker for JavaScript. The difference is that Typescript is more powerful, more complete, and more ecologically sound. Syntactically, Typescript is a superset of Javascript, and its relationship to Javascript is shown below:

Here’s what I know about Typescript outside of mandarin:

Typescript is a language that doesn’t even talk about C, C++, Java, or JavaScript. It’s a language that cuts across JavaScript because its variable types and syntax rules only apply to development and compilation. After compilation, it is converted to JavaScript for execution by the JavaScript interpreter. This means that learning typescript’s types and syntax doesn’t need to focus on its mechanics and storage rules at all. Instead, we need to understand how it maps to JavaScript types and syntax.

Here’s a brief description of how Typescript provides a solution to JavaScript typing issues, from the development and compilation phases. For details, see the official documentation.

1. Use Typescript syntax during development

As you can see from the figure above, Typescript supports ES6 syntax in addition to static typing. Let’s focus on how it addresses JavaScript types. Like Flow, Typescript type declarations involve three parts: type annotations in your own code, type annotations in the context API (Window/Node), and type annotations in third-party libraries (introduced in Lib). When there is a lack of type annotations in API and third-party library files, we usually solve this problem by introducing type declaration files.

Here is an example of adding a type declaration to your code:

// test.ts
function sum(m: number, n: number) :number {
	return m + n
}
Copy the code
Code time check

Because typescript belongs to a static language and IDE is very aware of its code, ides provide developers with powerful code-time checks, code hints, error alerts, and more.

2. Convert Typescript syntax at compile time

Like Flow, Typescript source code cannot be handed to the JavaScript interpreter for execution. We need to use the official TSC tools to compile typescript code into JavaScript code to solve JavaScript typing problems.

The following is a brief overview of Typescript compilation workflow:

  • Install the typescript
yarn add typescript --dev
Copy the code
  • Write the compile configuration: tsconfig.json
#1. Generate the. Flowconifg configuration file, where you can configure check sources, check rules, and check output positions
yarn tsc --init

#2. Modify the Tyscript configuration file, mainly involving the compilation of input file location, output file location, compilation rules, etc
# xxx
Copy the code
  • Read compile configuration performs compile
yarn tsc
Copy the code
  • At the end of compilation, the JavaScript code is obtained successfully, and the code is modified according to the error message of compilation.

3.Typescript type system

A quick note on Typescript’s type system. Typescript documentation classifies its types into the following categories:

type meaning The sample
basic Types Basic types of Number, Tuple, Void…
Interfaces The interface type { x : ‘xx’ } / interface xxx { x ‘xx’}
Unions and Intersection Types Types of union and intersection object | null
Literal Types Literal type 1 | 2 | 3
Enums Enumerated type Enum x { x ‘1’ }
Functions Function types function (m: number): Void { // xxx,no return }
Classes Class types Complete Java classes, access control, single inheritance and multiple implementation
Generics The generic Value generics: Array<number>, function generics, class generics

As a new static language, Typescript’s type system has absorbed many of the best types from other languages, especially Java. For these types of constraints, we could have done the same with the original solution by adding type judgments to the code. While using typescript leads to increased initial development, it allows us to write hand-typed, better-performing, and maintainable JavaScript code without a lot of typing. If you want to be a good coder in JavaScript, I don’t have to tell you to embrace Typescript!

The cost of learning typescript is low, especially for developers who have experience with static languages. Because it only involves development and compilation, we just need to understand the various types of typescript and be familiar with how to write good typescript code.

The end of this article, audience master you go, welcome to visit next time.