Leveraging TypeScript Advanced Types for Robust Data Modeling

Learn how to use TypeScript’s advanced types like union, intersection, mapped types, and conditional types to build more reliable and scalable data models.

TypeScript is a powerful tool for building reliable applications by adding static types to JavaScript. While beginners often use basic types like strings and numbers, TypeScript also offers advanced types that help create robust and flexible data models. In this tutorial, you’ll learn how to leverage union types, intersections, mapped types, and conditional types to build smarter and safer TypeScript code.

### Union Types Union types allow a variable to be one of multiple types. This is useful for data that can have different forms.

typescript
type ID = number | string;

function printId(id: ID) {
  if (typeof id === "string") {
    console.log(`ID is a string: ${id.toUpperCase()}`);
  } else {
    console.log(`ID is a number: ${id}`);
  }
}

printId("abc123"); // ID is a string: ABC123
printId(101);      // ID is a number: 101

### Intersection Types Intersection types let you combine multiple types into one. This comes in handy when you want an object that meets several type requirements simultaneously.

typescript
interface User {
  name: string;
  age: number;
}

interface Employee {
  employeeId: number;
}

type EmployeeUser = User & Employee;

const user: EmployeeUser = {
  name: "Alice",
  age: 28,
  employeeId: 1024
};

### Mapped Types Mapped types help you transform existing types into new types. For example, you can make all properties in an interface optional or readonly.

typescript
interface Task {
  title: string;
  completed: boolean;
}

type OptionalTask = {
  [P in keyof Task]?: Task[P];
};

const task1: OptionalTask = { title: "Learn TypeScript" };

### Conditional Types Conditional types allow you to select one of two types based on a condition. This is very useful for creating flexible and reusable type logic.

typescript
type IsString<T> = T extends string ? "Yes" : "No";

type Test1 = IsString<string>; // "Yes"
type Test2 = IsString<number>; // "No"

### Putting It All Together Let's create a generic function that updates an object, but only allows keys present on the original object. This uses generics, keyof, and mapped types.

typescript
function updateObject<T>(obj: T, updates: Partial<T>): T {
  return { ...obj, ...updates };
}

const userProfile = {
  name: "John",
  age: 30
};

const updatedProfile = updateObject(userProfile, { age: 31 });
console.log(updatedProfile); // { name: "John", age: 31 }

### Summary Using TypeScript's advanced types like union, intersection, mapped, and conditional types offers powerful tools to model your data more robustly. These features help reduce bugs and write clearer, more maintainable code. Start experimenting with these types today to improve your TypeScript skills!