DEV Community

Mikhail Potapov
Mikhail Potapov

Posted on

ūüĒ• Naming Interfaces in TypeScript: IUser vs User

In TypeScript, it is common for developers to prefix their interfaces with "I" (e.g., IUser) following the Hungarian notation. However, not all developers adhere to this convention.

I used to prefer using the "I" prefix for my interfaces as I believed it improved the reliability and clarity of my code. I also extended this convention to types, like TUser.

However, I encountered an issue when I needed to convert some interfaces into types, specifically when my interface became a union type of other interfaces. This necessitated replacing all the "I" prefixes with "T" throughout the codebase. These changes proved to be cumbersome, unnecessary. This issue has occurred multiple times for me and my colleagues, leading us to abandon the use of the "I" prefix.

I would like to know your thoughts on this matter. Do you also use prefixes for your interfaces?

Top comments (10)

ant_f_dev profile image
Anthony Fung

I don't think it's Hungarian notation as such - more C# convention. The typical Hungarian notation is more like iCount (for int), dwRadius (for double), szUsername (for string), lMilliseconds (for long).

I still prefix interfaces with I out of habit, but I did notice that the TypeScript handbook shows an example of interface declaration without the prefix. That said, I'm sure there was an I in earlier examples of the language.

All things considered, I'd probably say consistency is the most important thing. If your project already uses I, keep doing so or do a refactor to remove it everywhere (resource-permitting). When working on new projects, it might be best to go without.

haaxor1689 profile image
MaroҰ Beҕko

Step one, stop using interfaces and use types only. Apart from module augmentation, which should basically only be used by libraries anyway, there is nothing types can't do that interfaces can.

What you can also do with types is to name them the same as the value they represent and typescript will know which to use based on context. It's useful for use cases like zod schemas.

export const MyShema = z.object({ ... });
export type MySchema z.infer<typeof MySchema>
Enter fullscreen mode Exit fullscreen mode
intrnl profile image
intrnl • Edited

Note that this can be very disastrous if parts of your app (like on a monorepo) generates type declarations for consumption

It's heavily preferred to use interfaces over types if so

I think it might've been fixed already but it's still worth noting anyways, I personally prefer interfaces when able to because it's explicitly clear

haaxor1689 profile image
MaroҰ Beҕko

Oh damn, didn't know about this bug. Still it's just a temporary workaround and not something I'd switch over to using combination of types and interfaces.

matthewdean profile image
Matthew Dean • Edited

The official TypeScript style guide says to not use I for interfaces for a number of reasons. Another reason is that class definitions can serve as types, so it can quickly become inconsistent. If someone is using ‚ÄúI‚ÄĚ for interfaces, they‚Äôre probably coming from C# and have misunderstandings about TS/JS.

thegrimsilence profile image
Grim • Edited

I prefix interfaces only. When I first started coding I used IUser, TUser, EUserRole, but it all became redundant eventually. So now I use interfaces for everything until it needs to be a type. I prefix all interfaces with I, as in my book Interfaces are to be implemented but not just tossed around. Type are for unions and generics, enums are for a selection of limited values. And I never use class definitions as types if it can be avoided as that’s what interfaces are for.

But I prefer DI, so I usually use the interfaces to give the types needed from an injected service.

But I’ve spent 3 years tearing apart VS Code’s repo and learning programming that way as a real world example vs tutorial hell.

cmcnicholas profile image
Craig McNicholas

I avoid using prefixes for anything. It's refactoring hell when you have to change those types and there is no real way to guard against inconsistency.

The real question is "why do I need to know?", there's very few occasions where you need to know what you're working with is an interface or concrete (and it should be an interface anyway) if you're following SOLID which if you're using OO you should be considering anyway.

nathanelcorpuz profile image

This is very interesting. I am new to TypeScript (2 weeks), and saw npm libraries use the IUser convention.

fardelian profile image

That's when you're supposed to use your IDEs refactoring functionality

bwca profile image
Volodymyr Yepishev

It depends, I go with what the team decides to go, but my personal preference is not having the I prefix, since it's what contributors to typescript choose, though I am not among their numbers.