DEV Community

Cover image for Flexible Code Without Losing Type Safety with TS Generics
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Flexible Code Without Losing Type Safety with TS Generics

When working with TypeScript, you quickly run into a common problem:

👉 You want your code to be reusable, but also type-safe.

At first, it’s tempting to use any to make things flexible… but that comes at a cost:

  • You lose type safety
  • You lose autocomplete
  • You introduce hidden bugs

This is exactly the problem that TypeScript Generics solve.

They let you write reusable code without sacrificing type safety.

In this article, we’ll explore:

  • What Generics are
  • What problem they solve
  • Practical examples you’ll actually use
  • Best practices to avoid common mistakes

Let’s dive in.

🤔 Problem with type reusability

When you want your function to be reusable, you usually end up with this any approach:

function identity(value: any): any {
  return value
}
Enter fullscreen mode Exit fullscreen mode

It works but it also comes with problems such as no type safety, no IntelliSense, and can easily lead to break things.

The second problem is code duplication:

function identityString(value: string): string {
  return value
}

function identityNumber(value: number): number {
  return value
}
Enter fullscreen mode Exit fullscreen mode

With this approach, we are breaking the Don't Repeat Yourself (DRY) rule which also makes the code harder to maintain and less scalable.

🤔 Solution: TypeScript Generics

Generics allow you to create components, functions, or classes that work with multiple types, while still preserving full type information.

Think of them as:

👉 “Type placeholders” that get filled in later

Basic example:

function identity<T>(value: T): T {
  return value
}
Enter fullscreen mode Exit fullscreen mode

Here:

  • T is a generic type
  • It represents whatever type you pass in

Usage:

identity<string>("hello") // string
identity<number>(123)    // number
Enter fullscreen mode Exit fullscreen mode

TypeScript automatically knows what comes out based on what goes in.

🟢 Practical Examples

Let’s look at real-world scenarios where generics shine.

✅ Example 1: Reusable API Response Type

Very common pattern in frontend apps:

type ApiResponse<T> = {
  data: T
  error: string | null
}
Enter fullscreen mode Exit fullscreen mode

Usage:

type User = {
  id: number
  name: string
}

const response: ApiResponse<User> = {
  data: { id: 1, name: "John" },
  error: null
}
Enter fullscreen mode Exit fullscreen mode

Now your API types are consistent, reusable, and fully typed.

✅ Example 2: Generic Array Helper

function getFirstItem<T>(arr: T[]): T {
  return arr[0]
}
Enter fullscreen mode Exit fullscreen mode

Usage:

const number = getFirstItem([1, 2, 3]) // number
const string = getFirstItem(["a", "b"]) // string
Enter fullscreen mode Exit fullscreen mode

TypeScript knows exactly what type is returned.

✅ Example 3: Generic Props in Vue

Check out my other article where I have explained this topic in more details here.

✅ Example 4: Constraining Generics

Sometimes you want flexibility — but with rules.

function getLength<T extends { length: number }>(value: T) {
  return value.length
}
Enter fullscreen mode Exit fullscreen mode

Usage:

getLength("hello") // ✅
getLength([1, 2, 3]) // ✅
getLength(123) // ❌ error
Enter fullscreen mode Exit fullscreen mode

With this approach, you ensure flexibility but also controlled structure.

✅ Example 5: Keyof + Generics

function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}
Enter fullscreen mode Exit fullscreen mode

Usage:

const user = {
  id: 1,
  name: "John"
}

getProperty(user, "name") // ✅
getProperty(user, "age") // ❌ error
Enter fullscreen mode Exit fullscreen mode

This is extremely powerful for forms, dynamic access, or utilities.

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

🧪 Advance skills

A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.

Check out Certificates.dev by clicking this link or by clicking the image below:

Certificates.dev Link

Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!

✅ Summary

TypeScript Generics are one of the most powerful features in the language. They let you write code that is both flexible and safe — which is exactly what you want in modern applications.

Once you start using them properly, it’s hard to go back.

Take care!
And happy coding as always 🖥️

Top comments (0)