What Is TypeScript?

TypeScript is a superset of JavaScript that adds optional static type annotations. Every valid JavaScript program is also a valid TypeScript program, which means you can adopt it incrementally without rewriting your existing code. The TypeScript compiler checks your types at build time and outputs plain JavaScript that runs anywhere.

The real value of TypeScript goes beyond catching type errors. It enables richer IDE support, including autocompletion, inline documentation, and automated refactoring. Once you experience developing with full type information, it becomes difficult to go back.

Your First Types

The basic type annotations in TypeScript are straightforward. You add a colon after a variable name or parameter, followed by the type.

let username: string = "developer";
let isActive: boolean = true;
let loginCount: number = 42;

function greet(name: string): string {
  return `Hello, ${name}!`;
}

TypeScript also supports more advanced types like union types, generics, and utility types that allow you to express complex relationships in your data.

Interfaces and Type Aliases

Interfaces and type aliases let you define the shape of objects. They are one of the most commonly used TypeScript features.

interface BlogPost {
  title: string;
  slug: string;
  publishedAt: Date;
  tags: string[];
  content: string;
  draft?: boolean;
}

function getPostUrl(post: BlogPost): string {
  return `/blog/${post.slug}`;
}

The ? after draft marks it as an optional property. TypeScript will ensure that any object passed as a BlogPost has all the required fields while allowing draft to be omitted.

Working with Generics

Generics let you write reusable code that works with multiple types while maintaining type safety. They are essential for writing library code and utility functions.

function getFirst<T>(items: T[]): T | undefined {
  return items[0];
}

const firstPost = getFirst(posts); // type is BlogPost | undefined
const firstName = getFirst(names); // type is string | undefined

Generics ensure that the return type matches the input type, so you get accurate type information throughout your code.

Migrating Gradually

You do not need to convert your entire codebase at once. A practical migration strategy includes:

  • Start by renaming .js files to .ts and fixing the errors that surface
  • Enable strict mode in tsconfig.json for new files and gradually apply it to older ones
  • Add types to function signatures first, as they provide the most immediate benefit
  • Use the any type sparingly as a temporary escape hatch during migration

TypeScript pays for itself quickly through fewer runtime errors and a dramatically improved development experience.