DEV Community

The Practical Developer
The Practical Developer

Posted on Originally published at practicaldevblog.blogspot.com

TypeScript Explained: Types That Catch Bugs Before They Run

Introduction

JavaScript lets you pass anything to a function — a number, a string, or nothing at all — and only complains when the code actually runs. TypeScript adds a layer on top: you describe what shape your data should have, and the editor warns you the moment you get it wrong.

TypeScript does not replace JavaScript. It compiles down to plain JavaScript, so it runs everywhere JavaScript runs. You are adding safety checks, not learning a new language from scratch.

Your first type annotation

A type annotation is just a label after a variable or parameter, saying what it should be.

function greet(name: string): string {
  return `Hello, ${name}!`;
}
greet("Sara"); // Works
greet(42); // Error: Argument of type 'number' is not assignable to 'string'
Enter fullscreen mode Exit fullscreen mode

That error appears in the editor before you run anything. Without the annotation, greet(42) would happily return "Hello, 42!" and the bug would surface somewhere else, much later.

Describing an object with an interface

Real data is usually an object, not a single value. An interface describes the object's shape once, so every function that uses it agrees.

interface User {
  id: number;
  name: string;
  email: string;
  isAdmin?: boolean; // The ? means this field is optional
}
function sendWelcomeEmail(user: User) {
  console.log(`Welcome, ${user.name}!`);
}
sendWelcomeEmail({ id: 1, name: "Ali", email: "ali@example.com" });
Enter fullscreen mode Exit fullscreen mode

If you misspell email as emial, or forget it entirely, TypeScript flags it immediately. The ? on isAdmin means the field may be left out, which is how you describe data that is sometimes present and sometimes not.

Types that catch the classic mistakes

A few built-in types cover most beginner needs:

  • string, number, boolean — the basics.
  • string[] — an array of strings, so ["a", "b"] passes but [1, 2] does not.
  • User | null — a union type, meaning "a User, or null". This forces you to handle the missing case instead of assuming data always exists.
  • unknown — use this instead of any when you genuinely do not know the type yet. It forces a check before use, while any turns the safety off entirely.
function getUserName(user: User | null): string {
  if (user === null) {
    return "Guest";
  }
  return user.name; // TypeScript knows user is not null here
}
Enter fullscreen mode Exit fullscreen mode

When TypeScript is worth it, and when it is not

TypeScript pays off most when a project grows: more than one person working on it, data passed between many functions, or code you will still maintain in six months. For a tiny one-off script, plain JavaScript is faster to write, and adding types is overhead you may not need.

A good rule: start with JavaScript, and reach for TypeScript when you catch yourself thinking "I wish I knew what shape this data was supposed to be."

Takeaway

TypeScript is JavaScript plus a safety net. Annotate function parameters, describe objects with interfaces, and let the editor catch the wrong-type mistakes before your users do. You do not need advanced types to get most of the benefit.

Originally published at https://practicaldevblog.blogspot.com/2026/10/typescript-explained-types-that-catch.html

Top comments (0)