Why TypeScript?

JavaScript is dynamically typed: a variable's type is known only at run time, and reading a property that does not exist quietly produces undefined (undefined and null). Arithmetic on undefined then yields NaN, and the bug surfaces far from its cause. This shopping-cart function receives an item whose quantity property was named quantity instead of qty:

A misnamed property that JavaScript runs silently (cart.js)JavaScript
function total(items) {
  return items.reduce((sum, item) => sum + item.price * item.qty, 0);
}
console.log(total([{ price: 9.5, quantity: 2 }]));
Output
NaN

Nothing fails; the wrong total just flows into the page. In TypeScript you describe the expected shape once with an interface, annotate the parameter, and let the compiler compare every call against it:

The same function with types (cart.ts)TypeScript
interface Item {
  price: number;
  qty: number;
}
function total(items: Item[]): number {
  return items.reduce((sum, item) => sum + item.price * item.qty, 0);
}
console.log(total([{ price: 9.5, quantity: 2 }]));
Output
$ npx tsc --noEmit cart.ts
cart.ts(10,34): error TS2353: Object literal may only specify known properties, and 'quantity'
  does not exist in type 'Item'.

The error names the file, line, column and a stable code (TS2353) you can search for. Rename the property to qty and node cart.ts prints 19. The same types power your editor's completion, go-to-definition and safe renames, and when you change a type the compiler lists every line to fix.

TypeScript pays off most in code that lives long, has many contributors or is shared as a library. A short script may need nothing more than JSDoc comments (Declaration Files).