preface

I write JS fine, why use TS?

This article is written for those front-end beginners who have never used TS at all, and have not used structured languages, and have a certain mental burden on TS.

Faced with the overwhelming number of articles about TS, those who have not really started to use TS in the project may have just read a lot of nuggets articles, or read the official documents, and basically thought: Yeah, yeah, I know TS okay, I know that by putting a colon after a variable and a type, you can restrict variables, do you have to write all variables or functions? Why did I write the return type, VSCode still says return value is any? When should you use generics when generics are complicated? Where do I write the interface type definition?

Here, let’s break it up a little bit.

Who wrote TS for whom to read/use?

Conclusion first: TS is written by the definer to the user. To make it easier (VSCode hints) and safer (constraints) to use the methods or classes it provides.

With TS, there are two identities, defined and used.

VSCode prompt

For example, the definer specifies a method:

export function foo(name: string) :number {
  return name.length
}
Copy the code

As a user, you can clearly see the parameters and return values of this function from VSCode:

You do not need to look at the source code, you know, some complex methods, if there is no good annotation, look at the source code may not be able to quickly determine the parameters and return value types.

Use opportunely annotation

To provide a better VSCode hint, we can also comment the method:

/** foo function
 * @description count string size
 */
export function foo(name: string) :number {
  return name.length
}
Copy the code

The user sees:

Therefore, when you provide a method or class for others to use, you need to constrain the type so that users can use it better. At best, it means providing a third party library or framework for others to use, such as Axios lodash, etc. At worst, it means extracting a public method into your utils folder.

Type inference

Not all variables or return values need to be typed manually. Type inference can save a lot of code.

Let’s look at the following example:

export function splitString(str: string) {
  const separator = ', '
  return str.split(separator)
}
Copy the code

Separator :string can be used instead of separator:string, and TS will conduct type inference.

Furthermore, the return type is not defined. TS will infer the return type of splitString from the return type of split.

Type corollaries only work for simple types; complex cases need to be defined manually. VSCode prompts can be used to verify that the type is correctly inferred.

At the extreme, TS is meant to be fun for the user, with better hints and constraints to let you know if you have the right and safe methods to use. Not to add to your workload or mental burden.

VSCode does not prompt correctly

If you set an alias for your project path, it is possible that the imported method will not be correctly prompted.

We introduced the splitString method through an alias that no longer has the correct type hint. Since TS cannot parse @/foo/b correctly, you can add a Paths configuration to the compilerOptions option in tsconfig.json:

{
    "compilerOptions": {
        "paths": {
          "@ / *": ["src/*"]}}}Copy the code

This will parse the files under the alias correctly.

When to use generics

To understand this problem, you need to know what generics are and what problems they solve. Look at the documentation first.

Once you understand that generics are about making a component support multiple types. If you don’t know when to use generics, you don’t need them yet. When you hit a pain point, you will naturally think of generics.

Let’s say you define a method:

function foo (arg:number) :number {
    return arg
}
Copy the code

When you want this method to support string, if you don’t use generics, you might write:

function foo(arg: number | string) :number | string {
  return arg
}
Copy the code

So there’s a problem with this, where you pass in number and return string, and it’s not rigorous enough.

This is where generics come into your mind.

function foo(arg: T) :T {
  return arg
}
Copy the code

Of course, generics aren’t always easy to play with, and to get more advanced generics writing, look at the type definition files written by third-party libraries and see how others write various generics.

Where is the type definition?

The problem is the same as the problem above. If you don’t know when it’s going to work, you probably won’t be able to use it.

Simple ones that don’t reuse are written directly, as in the example above.

Typically, you need to reuse a custom type in the method implementation folder and export it for other users to use.

export type fooItem = string | number | null

function foo(arg:fooItem) :void {
    console.log(arg)
}
Copy the code

You can also use a folder for common data types. For example, when defining front and back interface data, you can do this:

// ./src/model/user.ts
export interface userReq {
  username: string
  password: string
}

export interface userRes {
  nickname: stringavatar? :string
  age: number
}
Copy the code

conclusion

This paper did not talk about the skills and advantages of TS, but gave simple answers and explanations based on personal experience to some mental problems encountered by novice students, which was rather messy.

In fact, TS is not as complex as imagined. The original intention of TS is to help developers and serve developers, and to enjoy the convenience and pleasure brought by TS. End with a line that almost everyone who has used TS says:

You can’t go back to JS if you use TS