• 5 Tips for Better TypeScript Code
  • By Anthony Oleinik
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: Zavier
  • Proofreader: regonCao, Niayyy

There are plenty of issues with native JavaScript, and TypeScript has plenty of solutions, some of which take a little digging to discover.

When I first started learning about the front end, I learned that TypeScript was designed to solve various problems with JavaScript. For example: passing wrong parameters, messy type swaps, accessing null values, and other common development issues.

Working with TypeScript has made me much more productive. I’ve also been studying TypeScript in detail, and I’d like to share some of what I’ve learned.

1. Null value merge operator

Sometimes TypeScript inserts optional chain operators for you when accessing properties. Like let t = myObj? .property, in which case the variable t will be assigned property or undefined. This is great, but it’s important to know exactly what’s going on here so you can use it in your own right and not just as a TypeScript auto-completion feature.

If we access a property in the normal way, like this: myobj. property, if myObj is undefined, we will get an error: “Cannot access property’ property’ of undefined”. This is obviously not what we expected, so use? If myObj is undefined, we stop accessing the property and assign t to undefined.

This is useful for avoiding errors, but sometimes we need a default value. For example, what if we have a text field that the user has never accessed, so that the internal value is undefined? We do not expect to send undefined to the back end. We can use the optional chain operator (which we just mentioned? .) with the null value merge operator. As follows:

sendFieldToServer(textField? .text ??' ')
Copy the code

This is a very elegant way to safely handle many boundary cases. That is, it ensures that undefined cannot be passed to a function, and TypeScript passes a string to sendFieldToServer.

This is because when the value on the left is undefined the merge operator will pass the value on the right to the function, which is an empty string.

In JavaScript, it’s easy to ignore all possible places in your code that might be undefined. Fortunately, TS will help us catch the error and warn you that sendFieldToServer cannot accept undefined as a parameter. We also use the optional chain operator and the null-value merge operator to keep the code rigorous.

2. Do not use the default export

One reason TypeScript is superior to JavaScript is the auto-completion capability of your code. Because in TypeScript, the editor knows exactly what objects you’re accessing and which properties are accessible. For example, if you have a dog object, the editor will prompt you to access its Bark method.

That is, if dog is in scope.

If we export dog by default in dog.ts, it looks like this:

default export interface Dog {
     bark: () = > void,}Copy the code

And then, when we import it, we can call it whatever we want. For example, you can import dog from another file and call it cat as follows:

import cat from 'dog.ts'

cat.bark()
Copy the code

This is the correct TypeScript code. That means if we go like this:

let t: dog = {
   bark: () = > console.log('woof! ')}Copy the code

TypeScript doesn’t know what dog is. There will be a red line under dog to indicate that dog is not defined. You need to find the location where dog is defined, import it manually, and make sure you name it dog.

This is what happens when you export by default. Export dog like this:

export interfacedog {.. }//export without 'default'
Copy the code

This means that now, in our other file, TypeScript knows where to look for an interface called dog when we type let t: dog. The editor automatically imports it for you, and TypeScript knows that you can access the Bark method.

Code completion is a nice feature. I see no reason to go with the default export, because regular exports are actually more useful. Even if you only need to export one, regular exports can still be handled easily.

Eslint has a no default export rule that can find any default export.

3. Limit the optional value of the string

Enumerations are one of the great capabilities of programming languages, and when JavaScript decides not to include them, it can be said that their superiority is greatly diminished.

Although TypeScript has enumerated types, you don’t necessarily need to use them. There is also some overhead associated with defining enumerated types. There are better ways to TypeScript.

t: "left" | "right" | "middle" = "middle"
Copy the code

This is also enumeration. Here, you can only assign t to a finite set of three values. Here we define it in one line of code, and TypeScript restricts assigning any other value to t. TypeScript reports an error if we try t=”center”. We can be 100% sure that the value of t is one of these three values, so when we access t, we can infer what the value of T is.

Meanwhile, t is still a normal string. We can normally concatenate it with other strings and display it on the interface.

4. Using the Map < T >

One of the nice things about JavaScript is that it has a flexible prototyping mechanism. You can add any property to any object. myObj.nonExistantField = “Is This” + 12312 + “A string or a number? Who Cares!” * 4, however, we omitted some, such as:

  1. Prototype access is relatively slow;
  2. Not easy to traverse (you need to useObject.keys(myOjb)Or otherwise);
  3. If every programmer just added attributes directly to the object, it would be hard to handle;
  4. There may be undefined attributes.

You can do similar things in TypeScript, such as allowing values of type any, but this is not recommended.

Instead, we can use Map. It also exists in native JS, but in JS it has no type restriction, so it’s not as useful. As follows:

let myMap: Map<string.string> = new Map(a)Copy the code

This will create a map that solves the problem I mentioned with the prototype-based key-value mapping.

  1. It is very fast to access: HashMap requires O(1) time complexity, as does add;
  2. usemap.forEach(), it can be easily traversed;
  3. You can put anything in there as long as the key and value are of the right type;
  4. Undefined can be avoided (as long as the constraint type does not include undefined).

Map is useful, and it’s the most frequently asked data structure question in an interview. In my opinion, they are much better than prototype-based mappings. If you try to allow the keys of an object to be arbitrarily defined, you are probably using the wrong data structure.

5. Configure esLint config/tsconfig

In general, it is necessary to configure the code format using ESLint or TSConfig. For example, I used to use Python, and I prefer the non-semicolon style. I have esLint configured so that when I accidentally enter a semicolon, the editor will immediately warn me.

In my opinion, keeping double quotes consistent makes code look prettier, so I also added a double quote configuration in ESLint.

I’m a big fan of pattern matching, so I configure it to be mandatory in my tsconfig.

I prefer no-default-export, so I set it to mandatory as well.

I highly recommend that you take the time to review all the configuration in.tsconfig or.eslintrc and personalize it. Then, back up these files so you can easily paste them in when you start a new project.

Sometimes I find it comforting to see that my code is consistent. As an added benefit, when other people are involved in the project, they also follow the rules agreed upon in.tsconfig and.eslintrc, so that we can ensure consistent code style throughout the project.


All right! These are my five suggestions for TypeScript coding. I’m also always looking for more advice, so if you have any points you think are worth watching, feel free to leave a comment!

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.