Avoid Redundant Properties in TypeScript Interfaces

You know that feeling when you meet someone and they forget your name? Kinda annoying or awkward, right? That’s pretty much what it’s like when you're working with data but don’t know its type—it’s like the data doesn’t have a name. So, before we jump into how to cut down on redundancy in TypeScript interfaces, let’s talk about why interfaces matter in the first place, what they’re for, and how to use them the right way. interface User { name: string; age: number; } Interfaces help us understand the data we get from the backend or send from the frontend, so we can work with it the right way. As your project grows, it’s easy to make mistakes—like treating a string as a number, or the other way around. That’s when bugs pop up and things get frustrating real quick. Most of the time, it’s because the data isn’t clearly defined. That’s why every field should have a proper type, so you know exactly how to use it. We often get data in JSON format that looks something like this: { "name": "lyla", "age": 12 } Now, a lazy way to handle this is by assigning the data to a variable with the any type—basically telling TypeScript, “I don’t know what this is.” let student: any; The problem? You have no clue what’s actually in that object. So when you do something like this: console.log("my student:", student.nickname); It won’t throw an error—even though the nickname doesn’t exist—because any disables type checking. Instead, try this: interface User { name: string; age: number; } let student: User; student = { name: 'lyla', age: 12 }; console.log(student.email); // ❌ TypeScript will throw an error here console.log(student.name); // ✅ This works fine With an interface, TypeScript can warn you if you’re trying to access something that doesn’t exist, helping you catch bugs early. I hope my explanation about interfaces was easy to follow. Now let’s move on to how we can reduce redundant properties in TypeScript interfaces. 1. Inherit Shared Properties In a real project, it’s pretty common to deal with different data types that share some of the same properties. For example, let’s say you have data for both students and lecturers. They both have name, age, and email—but the lecturer also has an extra property like phone_number. A lot of beginner TypeScript developers might write something like this: interface Student { name: string; age: number; email: string; } interface Lecturer { name: string; age: number; email: string; phone_number: number; } Now, this isn’t technically wrong—it’ll work just fine. But it’s not the cleanest way to write it. You can make it better (and DRY) like this: interface Student { name: string; age: number; email: string; } interface Lecturer extends Student { phone_number: number; } This way, you avoid repeating code and make your interfaces easier to maintain. 2. Use utility (pick ,omit, etc) Let’s say you only need the name property from the Student interface. Instead of creating a whole new interface, you can use TypeScript’s Pick utility: type MandatoryProperties = Pick; The Pick utility lets you grab specific properties from an existing interface—super useful when you only need part of the data structure. On the flip side, if there’s a property you don’t need, you can use the Omit utility: type MandatoryProperties = Omit; Omit removes specific properties from an interface. So in this case, you get a type with everything from Student except the email. These utilities help keep your code cleaner and avoid unnecessary duplication. Use Intersection (&) You can also combine two interfaces using an intersection—this can really speed things up and keep your code neat. interface Student { name: string; age: number; } interface Lecturer { nip: string; } type User = Student & Lecturer; Now User has all the properties from both Student and Lecturer. Pretty handy, right? So those are some simple tips for TypeScript developers to cut down on redundant properties and write code that’s cleaner, more efficient, and easier to manage.

Apr 29, 2025 - 17:52
 0
Avoid Redundant Properties in TypeScript Interfaces

You know that feeling when you meet someone and they forget your name? Kinda annoying or awkward, right? That’s pretty much what it’s like when you're working with data but don’t know its type—it’s like the data doesn’t have a name. So, before we jump into how to cut down on redundancy in TypeScript interfaces, let’s talk about why interfaces matter in the first place, what they’re for, and how to use them the right way.

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

Interfaces help us understand the data we get from the backend or send from the frontend, so we can work with it the right way. As your project grows, it’s easy to make mistakes—like treating a string as a number, or the other way around. That’s when bugs pop up and things get frustrating real quick. Most of the time, it’s because the data isn’t clearly defined. That’s why every field should have a proper type, so you know exactly how to use it.

We often get data in JSON format that looks something like this:

{
  "name": "lyla",
  "age": 12
}

Now, a lazy way to handle this is by assigning the data to a variable with the any type—basically telling TypeScript, “I don’t know what this is.”

let student: any;

The problem? You have no clue what’s actually in that object. So when you do something like this:

console.log("my student:", student.nickname);

It won’t throw an error—even though the nickname doesn’t exist—because any disables type checking. Instead, try this:

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

let student: User;
student = { name: 'lyla', age: 12 };
console.log(student.email); // ❌ TypeScript will throw an error here
console.log(student.name);  // ✅ This works fine

With an interface, TypeScript can warn you if you’re trying to access something that doesn’t exist, helping you catch bugs early.

I hope my explanation about interfaces was easy to follow. Now let’s move on to how we can reduce redundant properties in TypeScript interfaces.

1. Inherit Shared Properties

In a real project, it’s pretty common to deal with different data types that share some of the same properties. For example, let’s say you have data for both students and lecturers. They both have name, age, and email—but the lecturer also has an extra property like phone_number.

A lot of beginner TypeScript developers might write something like this:

interface Student {
  name: string;
  age: number;
  email: string;
}

interface Lecturer  {
  name: string;
  age: number;
  email: string;
  phone_number: number;
}

Now, this isn’t technically wrong—it’ll work just fine. But it’s not the cleanest way to write it. You can make it better (and DRY) like this:

interface Student {
  name: string;
  age: number;
  email: string;
}

interface Lecturer extends Student {
  phone_number: number;
}

This way, you avoid repeating code and make your interfaces easier to maintain.

2. Use utility (pick ,omit, etc)

Let’s say you only need the name property from the Student interface. Instead of creating a whole new interface, you can use TypeScript’s Pick utility:

type MandatoryProperties = Pick;

The Pick utility lets you grab specific properties from an existing interface—super useful when you only need part of the data structure.

On the flip side, if there’s a property you don’t need, you can use the Omit utility:

type MandatoryProperties = Omit;

Omit removes specific properties from an interface. So in this case, you get a type with everything from Student except the email. These utilities help keep your code cleaner and avoid unnecessary duplication.

Use Intersection (&)

You can also combine two interfaces using an intersection—this can really speed things up and keep your code neat.

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

interface Lecturer {
  nip: string;
}

type User = Student & Lecturer;

Now User has all the properties from both Student and Lecturer. Pretty handy, right?

So those are some simple tips for TypeScript developers to cut down on redundant properties and write code that’s cleaner, more efficient, and easier to manage.