Have you ever felt the despair when you failed to find a problem with DEBUG for a year, only to find out that the variable name was incorrectly written? Have you ever felt the fear of Uncaught TypeError in your production line code? SAO years, you feel the code to find ten thousand files can not find the method definition of grievance?

Pick up the keyboard and let’s drag the life-killing code into the trash! (cross)

series

Issue: TS Amway Guide

The second issue: TS in JS Practice Refers to north

preface

It is understood that at present there are quite a number of students do not want to learn TS, after all, there is no time (bu) between (dong). Unfortunately I was one of them two months ago. In see especially big with TS to write vue3, ready to move I carefully stepped into this pit. After a long day of groping, I realized the truth

After a while of understanding, I wrote this article to provide a benefit analysis of TS for those of you who are hesitant to learn TypeScript or are still on the fence. I hope it will impress you on the screen.

amway

Is TS hard to write? It’s not hard to. The easiest way to do it is in three steps.

  1. Find a JS file
  2. Press rename
  3. So let’s change.js to.ts

And you’re done!

(Don’t hit people in the face, but live on it…)

⬇️ TS Initial experience

– ts is what

Ts is a superset of JS, which means that js syntax can also run in TS. Ts, on the one hand, adds a lot of restrictions to JS, on the other hand, it expands js capabilities, just like ES6 provides so many magical syntactic sugar. As long as you follow certain rules to write JS, you can enjoy the benefits of TS.

Of course, because ts is powerful enough now, and has its own vscode escort, it is convenient for those of us who did not think (LAN) dare (de) to think of the helpless pain programmers.

The amount of work required to transform JS into TS depends largely on how detailed and descriptive you want your code to be. The simplest, as mentioned above, is to change the extension name (of course, it will probably not pass the various static checks). The more you write, the more likely the people who use your code will like what you write.

The following is a brief introduction to the TS syntax for later understanding.

– TS Syntax introduction

// 'XXX: number' specifies a number type
const num: number = 123

// Declare a function argument type (number and any) and return value (void)
function fn (arg1: number, arg2: any) :void {
    // todo
}
fn(num, [1.2.3.4])

// Declare an interface
interface IPerson {
    name: string // IPerson needs to contain a name attribute of type string
    age: number // IPerson needs to contain an age attribute of type number
    family: string[] // IPerson needs to include a family attribute, which is an array of stringssex? :'male' | 'woman' // IPerson has an optional sex attribute, with the value 'male' or 'female' or undefined
}
// Use the IPerson interface to define an object. If the object does not conform to the IPerson definition, the compiler will raise a red flag
const person: IPerson = {
    name: 'wang',
    age: 12,
    family: ['daddy'.'mother'],}// type is like interface, which is the same as declaring IPerson as interface
type IPerson2 = {
    name: string
    age: number
    family: string[] sex? :'male' | 'woman'
}
// So we can define it directly
const person2: IPerson2 = person
Copy the code

Some students may read the above introduction, will say:

“There’s so much more code to write, and there’s an increase in file size, what the hell?”

In general, TS needs to be compiled into JS to run. When compiled, it looks like this:

// 'XXX: number' specifies a number type
var num = 123;
// Declare a function argument type (number and any) and return value (void)
function fn(arg1, arg2) {
    // todo
}
fn(num, [1.2.3.4]);
// Use the IPerson interface to define an object. If the object does not conform to the IPerson definition, the compiler will raise a red flag
var person = {
    name: 'wang'.age: 12.family: ['daddy'.'mother']};// So we can define it directly
var person2 = person;
Copy the code

Through the human diff, it was found that all the ts code was removed after compilation.

Maybe some of you want to ask:

“What’s the good of it?”

Don’t worry, continue to read 🤓

Application scenarios

This section introduces several application scenarios of TS, give some inspiration ~

-Use my code, do as I say

You have to do a lot of fault-tolerant things to your code to make it robust.

If you succeed in avoiding eye blotches because of your age, use your own method to miss a parameter here, pass the wrong parameter type there. There will often be unreliable users who don’t look at the API documentation you’ve worked so hard to create. Finally out of the problem also blame you did not do a good deal of compatibility, leadership group in a scold.

We have to be like the mother of the child, wondering what kind of crap the child is going to pass in, and then adding branches to the code.

Now with TS, you will be able to pass in a friendly “what did you write” message.

Let’s first define a function in terms of TS

interface IArgs { name: string age: string } function youFoo (arg1: string, arg2: 'a'|'b', arg3: IArgs) {// there is nothing to do here, you can pass in}Copy the code

If colleague Xiaoming writes so

youFoo('sss'.'c', {
    name: 'xiaoming',
    age: 18
})
Copy the code

He’ll see what doesn’t seem right, right

The second parameter required ‘a’ or ‘b’, so Ming silently corrected it, but found

Age is a string.

So Xiao Ming changed his MMP at the same time.

– to find the document

When we’re at work, we usually like to have an extra screen. You can open chrome, look up questions, find documents, etc. But often have to see the speed of the network, with a search to search what API, encountered in the countryside to write code, minutes have to shi heart.

With TS, we solved the problem of da gaI:

First, write the method according to the structure like this:

/** * A method: Generate the error information * * @ param {string} message prompt information, such as ` you have a error ` * @ param {number | string} code error code, @param {string} type, (https://www.google.com) * * ' 'js * // demo * genErrMsg('demo', 10086) * * ``` */ export function genErrMsg (message: string, code: number | string, type?: ('demo1' | 'demo2')): String {return (message | | ` network is busy, please try again later `) + (code? ` (${code}) ` : ` `)}Copy the code

Then the experience during the use is as follows:

The experience is even better in the more complete lib, which, in addition to jquery at the beginning, also includes:

– Carelessness

Read the following JS code and ask: How many bugs does the code below the dividing line have?

// careless.js
let foooo = 1
let fooo = 1
let fooooooo = 1
let foo = 1
let foooooo = 1
let test = 12
const obj = {
    fn1 () {},
    fn2 () {},
    fn4 () {},
}

/*************** Where is the code below the split line buggy? * * * * * * * * * * * * * * * * * /

obj.fn3()

console.leg(fooooo)

function test () {
    alert(tast)
}
Copy the code

/ *

支那

支那

***** Answer line *****

支那

支那

* /

Do you feel a little blind?

Try changing.js to.ts

– Hidden problems

If the previous JS code was able to instantly tell something was wrong with a glance, then the following is not so easy

Read the following JS code and ask: How many bugs does the code have?

import * as utils from './utils'

utils.genErrMsg(10086.'this is error') // genErrMsg function mentioned above

let dom = window.document.getElementById('foo')
dom.className = 'add'
Copy the code

/ *

支那

支那

***** Answer line *****

支那

支那

* /

Try changing.js to.ts

The questions are as follows:

1. The first argument to genErrMsg should be string

2. GetElementById may also return null

– The interface data is not known

In the process of maintaining code, it is often possible to encounter an interface that does not know what data is present, and we usually need to consult the interface documentation. However, when the number of times, or the background big guy a pit up, changed the field, may be checked to doubt life.

If you use TS, you might have a different script

Suppose you have an interface as follows

We wrote the following TS code for this interface:

interface IPriceData {
    /** 标识 */
    cbf: string
    /** id */
    id: string
    /** Market price */
    m: string
    /** background price */
    op: string
    /** Front desk price */
    p: string
}

// Insert IPriceData into the array
type IPriceDataArray = IPriceData[]

function getPrice () {
    IPriceDataArray = IPriceDataArray = IPriceDataArray = IPriceDataArray
    return new Promise<IPriceDataArray>((resolve, reject) => {
        $.get('https://xxxxxxx/prices/pgets? ids=P_100012&area=&source=', data => {
            resolve(data)})})}Copy the code

When the getPrice function is called, the experience is as follows:

You don’t need to look at the documentation every time you maintain this function. If the background suddenly changed the field, in the process of checking we can immediately find the problem, and then take the data to question: you tm changed things let me take the blame… (10,000 words omitted)

– Enhanced class and enum

As we all know, the class in JS is a syntactic sugar. If you want to learn a strongly typed language, the writing method is half-baked.

But in TS, class is enhanced (still syntactic sugar, but sweeter)

Let’s look at the picture and say:

In vscode, the public, private, protected, and static properties under ts are not allowed and only public properties are displayed.

Ts also provides enum syntax sugar:

enum HttpCode {
    / * * * / success
    '200_OK' = 200./** A new resource has been generated */
    '201_Created' = 201./** The request will be processed later */
    '202_Accepted' = 202./** The resource does not exist */
    '204_NoContent' = 204./** The requested resource has a selection of feedback */
    '300_MultipleChoices' = 300./** Permanent transfer */
    '301_MovedPermanently' = 301./** Temporary transfer */
    '302_MoveTemporarily' = 302,
}

HttpCode['200_OK']
HttpCode[200]
Copy the code

Compared with a key-value defined by a simple object, a value can only be accessed through a key, but not a key. However, in enum, both positive and negative keys can be used as keys.

After compiling the code interested students can understand ~

"use strict";
var HttpCode;
(function (HttpCode) {
    / * * * / success
    HttpCode[HttpCode["200_OK"] = 200] = "200_OK";
    /** A new resource has been generated */
    HttpCode[HttpCode["201_Created"] = 201] = "201_Created";
    /** The request will be processed later */
    HttpCode[HttpCode["202_Accepted"] = 202] = "202_Accepted";
    /** The resource does not exist */
    HttpCode[HttpCode["204_NoContent"] = 204] = "204_NoContent";
    /** The requested resource has a selection of feedback */
    HttpCode[HttpCode["300_MultipleChoices"] = 300] = "300_MultipleChoices";
    /** Permanent transfer */
    HttpCode[HttpCode["301_MovedPermanently"] = 301] = "301_MovedPermanently";
    /** Temporary transfer */
    HttpCode[HttpCode["302_MoveTemporarily"] = 302] = "302_MoveTemporarily";
})(HttpCode || (HttpCode = {}));
HttpCode['200_OK'];
HttpCode[200];
Copy the code

Advantages and disadvantages

Using TS, you can gain the following skill points:

  • Clear function parameters/interface attributes, increase code readability and maintainability
  • Static checking
  • Generating API documentation
  • With modern editor, various tips
  • Active community

And the cost of the technology

Maintainer (package author) The user
earnings Clear function arguments/interface attributes

Static checking

Generating API documentation
Clear function arguments/interface attributes

With modern editor, various tips
The price Tag type

Statement (interface/type)
Doesn’t work perfectly with some libraries (yes, vue 2.x)

Vue’s ts syntax needs to use the class style (which will be converted back to the original Vue constructor syntax at runtime), which is somewhat different from the familiar Vue style

This is because the environment of vue’s this is complicated, and it needs to be determined at runtime for ide. Therefore, when writing TS, you need to manually set the properties (such as props,data,methods, etc.) under this, which is very troublesome. Early TS did not support manual writing of the scope for this, and later designed a ThisType method specifically for it.

In the above code, we use the class notation, and all the required attributes are in this, avoiding the problem that the runtime can only determine the scope required under this.

On the other hand, because of the limited ability of TS hints, for example in a functional scenario, if the data source is a separate object, the experience will be worse.

Please read the following (this section is slightly beyond the category of the title ‘Amway’, if you don’t understand it, you can digest it later.)

interface IOptions {
    name: string
    age: number
    extra: {
        data: Object
        methods: Object}}// The options parameter must comply with the rules defined by IOptions
function sthConstructor (options: IOptions) {}

// The options object does not have any static checks and prompts for ts
const options = {
    name: 'peter',
    age: '13'.// error: Age should be a number
    extra: {
        data: [],
        methods: {}
    }
}
// Options float red error, however, the prompt content is too much garbage, key information is too deep
sthConstructor(options)
Copy the code

In the above scenario, we want to get full TS checking capability in options. There are three ways to do this:

1. Move the contents of options into the function

2. Define options with IObject

3. Provide a helper method

Of these three ways:

Method 1 is the easiest way, but it’s rarely seen in large projects.

Method 2 is commonly used by maintainers, but is expensive for consumers. Because the user needs to go to lib to find the type of the method and import it.

Method 3 is the preferred method, as long as the maintainer provides a function wrapper like a helper, you can get the corresponding hint. Does it look like a vue TS decorator?

But I find none of the above solutions elegant, which is one of the current shortcomings of TS.

Ts in JS play

TypeScript and vscode are both sons of Microsoft, so there’s definitely more to work with, even if you’re using js files.

Here are two:

– Automatic prompt for configuration files

As long as there is a types file, all configurations can be automatically prompted:

/** * Webpack configuration automatically prompt ** to install the corresponding types package first: 'NPM i@types /webpack -d' ** @type {import('webpack').Configuration}
 */
const config = {
    
}
Copy the code

-js syntax check

Automatic prompts and static checks are also available in JS. Just Check JS in vscode setting. Although your JS code may be variously red 🤪

The previous example ⬇️ can also indicate some bugs in JS

Write in the last

Some students will ask: I just learn JS, can I learn TS? Can, and suggest, because will deepen the understanding of JS basic knowledge. The usage problem is solved by searching stackOverflow.

So where can I learn such a useful tool? Maybe you can refer to my study track:

Portal: Getting started with TypeScript

Portal – Learn TypeScript for Vue3 and experience TypeScript

Portal – A simple article that takes you 30 minutes to complete TypeScript, using pros and cons

Portal — Stack Overflow

Portal – Google

This year ts is popping up all over the place and seems to be a trend. All kinds of TS transformation, learning tutorials, experience appeared in the major learning, dating websites. Some of you may have noticed: Isn’t that what Java and other languages are left with?

Everyone wanted to be free when they were young, but as they got older, they were all under the thumb


Thanks @junning @zenghongtu for your comments

In this article, the Array generic (Array< XXX >) has been used to represent the Array in square brackets (XXX []).

The reason for this is that ts after 3.4 has a warning for Array generics in readonly scenarios. Use square brackets to avoid craters in complex scenarios.

// The readonly modifier can only be used on arrays and tuples in square brackets
let err1: readonly Set<number>; / / error!
let err2: readonly Array<boolean>; / / error!

let okay: readonly boolean[]; / / there is no mistake
let okay2: readonly [boolean.string]; / / there is no mistake
Copy the code

Hereby note.


If you think this article is valuable to you, please like it and follow us on our official website and WecTeam. We have great articles every week