When is it appropriate to use a semicolon?

TypescriptCoding Style

Typescript Problem Overview


I know that JavaScript (and thus TypeScript) support the omission of semicolons in many cases. Nevertheless I want to add semicolons to be unambiguous as suggested in TypeScript Deep Dive

However I cannot find a guide that lists where to use semicolon. For example look at the following code

class Person {
  private name: string; // A

  constructor(name: string) {
    this.name = name;
  }; // B

  public add = () => {
    return "C";
  }; // C
}; // D

I'm fairly sure to use a semicolon at A. But what about B, C, D and all the other cases not covered by my example?

I'm not asking where to omit semicolon but where to add them. An answer like always does not fulfill my needs since I cannot add a ; after public. I want to know where exactly to put semicolon.

Typescript Solutions


Solution 1 - Typescript

Just prefix lines starting with [, (, or ` with a semicolon and you're (almost) golden*

Using the same example as another answer:

var x = { xx : "hello", yy : "world"}
(function () {
    console.log("Hello World");
})();

We add a semicolon according to this rule:

var x = { xx : "hello", yy : "world"}
;(function () {

otherwise javascript thinks we're trying to call( some function, or reference[ some array. This is simpler, easier to follow, and it's visually easier to spot. You also need semicolons in for loops, but the .forEach method is a cleaner and easier method. I'd confidently say this one rule covers 99% of the scenarios you need to use a semicolon in javascript/typescript.

Following this method, it's important to associate a newline with terminating a statement.

*This returns the venerable undefined:

  return 
          7

After return, there's a newline, and the browser inserts a semicolon, terminating the statement like this:

  return; // this will return undefined.
          7
Do this instead:
  return (
          7
  )

Javascript is actually pretty smart with semicolons, there's an open paren, so no semicolon is inserted until the closing paren is found.

If you have a habit of putting semicolons everywhere and not knowing exactly when they are needed, you could read this for a several page long explanation: http://blog.izs.me/post/2353458699/an-open-letter-to-javascript-leaders-regarding

I admit most people will still just litter semi colons at the end of every line, but if you're new and just learning, this is the better approach.

Solution 2 - Typescript

Like some other modern languages derived from the C syntax, JavaScript syntax was designed to allow you to omit semicolons in almost all situations. I'd say use them always or use them never*. To use them "never" the long and short of it is that every statement goes on a new line and never begin a line with (, [, or `.

However, to use them "never", you should definitely be using a linter such as JavaScript Standard Style or eslint with its built-in semi rule to disable semicolons and its no-unexpected-multiline rule which will make sure that you avoid the few gotchas such as the following:

a = b + c
(d + e).foo()

The above is interpreted as a = b + c(d + e).foo(); Note that by following the above rule and not beginning a line with ( this situation is prevented.

Another common example is the following:

return
{
     hello: "world"
};

At a glance one may think this will be interpreted as returning an object, but it actually interpreted as return; and the code to define the object after the return statement is unreachable. Again, by following the rule of not beginning a line with { this is avoided.


  • *Okay, okay, not never, but almost never.

Solution 3 - Typescript

TL;DR: Always

Keep in mind: better safe than sorry

You should probably place them all the time. You don't need to place them in order for TypeScript to work, but you will avoid errors by doing so. ASI (Automatic Semicolon Insertion) works quite well most of time, but not always. Do you really want to run into a problem just because you didn't put a semicolon, and you keep overlooking the mistake? (Depending on your IDE, the mistake might actually be caught). But consider this perfectly valid Javascript.

 var x = { xx : "hello", yy : "world"}
 (function () {
     console.log("Hello World");
 })();

This is valid javascript (and thus valid typescript). This code will actually give an error. Uncaught TypeError: (intermediate value)(intermediate value) is not a function(…).

Which could be avoided by just placing a semicolon after the first line. You don't need it there, and if the next line wasn't that function line, it would probably work correctly. But you want to take that risk? It seems like taking the risk for mistakes over one extra character is not worth it to me. Plus, after a while, you just get used to place semicolons at the end of a line anyway;

Think of your colleagues

Another reason you might want to use them all the time is in the case of code changing. Your colleague might have to change your code - and in doing so thinks that the ASI will keep working even with his code change. Imagine that this is not the case, and that his change actually makes ASI do something wrong. Is it really worth that headache for your colleague? If he changes enough of your code and then suddenly runs into a lot of errors, he might be rather confused if he does not know the exact way in which ASI is working. You could save a potential colleague quite a bit of (unneccessary) work by just putting them everywhere.

Solution 4 - Typescript

You need to watch that you do not inadvertently add semi-colons but the best way to avoid that self-inflicted bug is not to use them except where required by the language.

This bug is as likely as the one and only case where omitting semicolons might not capture your actual intent:

for(int i = 0; i < count; i++); do()

There is one situation where your intent might be ambiguous, with the unusual style of starting a line with a ( or a [ character, since the newline doesn't terminate the statement in that case. The vast majority of the time it's precisely what you want, it's obvious when it's not, and you can dream up some statements with or without semicolons (as I showed above) that are problematic.

I'm not going to say it's irrational to use semicolons because it is so ingrained in the culture, but please ignore the irrational fear many attempt to support with a convoluted and inaccurate discussion of ASI or mad hand waving. It's pure dogma, friends.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionooxiView Question on Stackoverflow
Solution 1 - TypescriptDevin RhodeView Answer on Stackoverflow
Solution 2 - TypescriptScott WillekeView Answer on Stackoverflow
Solution 3 - TypescriptDylan MeeusView Answer on Stackoverflow
Solution 4 - TypescriptRick O'SheaView Answer on Stackoverflow