DEV Community

Shivam Singh
Shivam Singh

Posted on

7 Advanced TypeScript Concepts Every Developer Should Know

TypeScript is a powerful superset of JavaScript that adds static typing and other features to improve the development experience. While many developers are familiar with the basics, mastering advanced TypeScript concepts can significantly enhance your ability to write robust, maintainable, and scalable code. Here are 10 advanced TypeScript concepts every developer should know.

1. Union Types

Union types allow a variable to hold one of several types, giving you the flexibility to handle different data types while still keeping things type-safe. It's like having a multi-tool 🛠️ that can handle different tasks.

Example 1:

let value: string | number;

value = "Hello";
console.log(value); // "Hello"

value = 123;
console.log(value); // 123


Example 2:
type status = "review" | "published" | "expired";

function getJobStatus(status: status): string {
  switch (status) {
    case "review":
      return "Job is on Review";
    case "published":
      return "Job is Published";
    case "expired":
      return "Job is Expired";
    default:
      return "Unknown status";
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Intersection Types

Intersection types combine multiple types into one, requiring a variable to have all the properties of the combined types.

interface Person {
  name: string;
  age: number;
}

interface Employee {
  employeeId: number;
}

type Developer = Person & Employee;

const emp: Developer = {
  name: "Alice",
  age: 25,
  employeeId: 12345
};

console.log(emp);
Enter fullscreen mode Exit fullscreen mode

In this example, we’ve defined two types, Person and Employee, and then used an intersection to create a Developer type that combines both Employee and Person properties. This represents a developer's identity and role in the organization.

3. Type Guards

Type guards help you narrow down the type of a variable within a conditional block, ensuring type safety. Think of them as security bouncers 🚨 at a nightclub, letting only the right types in.

Example

function isString(value: any): value is string {
  return typeof value === "string";
}

function printValue(value: string | number) {
  if (isString(value)) {
    console.log(value.toUpperCase());
  } else {
    console.log(value.toFixed());
  }
}

printValue("Hello"); // "HELLO"
printValue(123); // "123"
Enter fullscreen mode Exit fullscreen mode

Type guards: because we all need a little security in our lives.

4. Conditional Types

Conditional types allow you to create types based on conditions, offering powerful type transformations. It's like a choose-your-own-adventure book 📚.

Example

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

type Result1 = IsString<string>; // "Yes"
type Result2 = IsString<number>; // "No"
Enter fullscreen mode Exit fullscreen mode

Conditional types are incredibly powerful, allowing you to create dynamic and flexible types based on conditions.

5. Mapped Types

Mapped types let you transform existing types into new ones by applying a transformation to each property.

Example

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

interface Todo {
  title: string;
  description: string;
}

const todo: Readonly<Todo> = {
  title: "Learn TypeScript",
  description: "Study advanced concepts"
};

// todo.title = "New Title"; // Error: Cannot assign to 'title' because it is a read-only property.


type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

interface User {
  id: number;
  name: string;
  email: string;
}

type NullableUser = Nullable<User>;

type NullableUser = {
  id: number | null;
  name: string | null;
  email: string | null;
};

// In this example, Nullable transforms each property of User to also accept null.
Enter fullscreen mode Exit fullscreen mode

6. Template Literal Types

Template literal types let you create types by combining string literals, making your type definitions more expressive.

Example

type Color = "red" | "green" | "blue";
type Brightness = "light" | "dark";

type Theme = `${Brightness}-${Color}`;

const theme1: Theme = "light-red";
const theme2: Theme = "dark-blue";

// const theme3: Theme = "bright-yellow"; // Error: Type '"bright-yellow"' is not assignable to type 'Theme'.
Enter fullscreen mode Exit fullscreen mode

Template literal types allow you to define a Theme type that must follow the pattern of Brightness-Color. It's like giving your types a style guide to follow.

7. Recursive Types

Recursive types are types that refer to themselves, allowing you to model complex data structures like trees and linked lists.

Example

Creating a recursive type for a tree structure:

interface TreeNode {
  value: number;
  left?: TreeNode;
  right?: TreeNode;
}

const tree: TreeNode = {
  value: 1,
  left: {
    value: 2,
    left: { value: 3 },
    right: { value: 4 }
  },
  right: {
    value: 5
  }
};
Enter fullscreen mode Exit fullscreen mode

Recursive types: because sometimes you need types that go on forever, like an infinite loop (but in a good way).

Conclusion

TypeScript is a powerful tool, and mastering these advanced concepts can make your code more robust, maintainable, and just plain awesome. As you continue to explore these advanced features, you'll find that your code becomes more concise, your type definitions more precise, and your overall development workflow smoother.

Additional Resources

Happy coding! 🎉

Top comments (0)