This TS naming convention is weird
Вставка
- Опубліковано 10 лип 2024
- Here are my top 4 rules for how to name your types in TypeScript.
Never pluralize: Unless your type is an array type, you should make it singular - even if it's a union of members.
Casing: Choose a different casing between your values and your types. This helps stop syntax highlighting getting confused.
Type Parameters: prefix your type arguments with T. If you've got only one type argument, you can use T. Otherwise, be more descriptive with your parameter names.
Avoid Unnecessary Prefixes: Prefixes like IUser and TOrganization might feel useful, but they're mostly just holdovers from the Java days.
00:00 Intro
00:14 Never Pluralize
01:18 Casing
01:50 Type Parameters
02:44 Unnecessary Prefixes
03:35 Outro
Become a TypeScript Wizard with my free beginners TypeScript Course:
www.totaltypescript.com/tutor...
Follow Matt on Twitter
/ mattpocockuk
Join the Discord:
mattpocock.com/discord
A note on 'everything is singular'. I thought of another case - bags of options.
Props, Options, Settings - all to me indicate a 'config object', not an array.
Weird how language works.
Awesome video. Quick question how do you deal with situations where you omit or extend parts? I havent figured out a decent way myself yet.
I suppose we've gotten very used to seeing these words pluralized, so when we see them as singular (Prop, Option, Setting) I, for one, consider it to mean a part that is extracted from that pluralized group. Options is not Option pluralized, but instead Option is an extracted unit of Options. So the plural becomes "default" and a singular version is the one that needs extra context. Does that make sense?
Personally I'd save the plural version for objects and special cases. For Route[] just use Route[].
i'm not hearing a difference
@mattpocockuk
Hi Matt, could you suggest me how to name the following definitions properly?
Suppose i have the following enum-like object:
const UserRole = {
ADMIN: "admin",
CUSTOMER: "customer",
MODERATOR: "moderator"
} as const;
And now i also want to define a type for this:
type UserRole = typeof UserRole[keyof typeof UserRole];
Is it ok to have both UserRole object and UserRole type?
preffix it with T, got it
TT TU TV
Great video as always, I really like idea of properly naming your the parameters to your generic types so much so that I've gone and updated the names in my codebase!
I'm so glad you've come along! Honestly, thank you so much for your content. I'm a dev on a small team building a huge system and I've been stumbling along for 2 years with zero previous react and TS experience-just getting by but knowing I'm doing things wrong. Finding legit senior level dev training on TS is a wish come true. Our proj will be refactored in the near future by me and I couldn't be more excited. I'm buying your course. And please keep content semi-focused on react if you would. :)
in react, always use a suffix Props if it's a prop interface of a component, eg. WidgetProps
Thx for pointing that out. Wondered what the correct way would be in case component and type name clash and have seen the suffix Props now recommended most of the times so I'll go with it :)
Hello Matt. I use the "I" prefix because I don't always remember the exact name of the interface and use ide hints. If I write "IU", then Ide will tell me only the names of the interfaces, because they all start with "I", for example "IUser, ITelegramUser, IGetUserResponse". Without the prefix, I'm more likely to see component and function names in tooltips.
As a C# developer, I use I to indicate interfaces, partially because it's a language standard, but also because an implementation can have the same name as the interface.
UserRepository - Unclear if it's an implementation or an interface.
IUserRepository - Very clear that it's an interface, which subsequently means that UserRepository is an implementation.
@@Dojan5 why would you name the implementation the same as the interface though? that's a thing I've never understood about C#. shouldn't the interface be the thing you're deriving your implementation from? this naming scheme implies the opposite, that the interface is just a clone of its implementation, but as an interface
@@darxoonwasser The interface is a contract, an outline of what you expect in a class, but not necessarily how.
Since a decently recent C# update you *can* add code to interfaces, but I've never actually seen this in practise and I personally think it's a bit of an antipattern.
Due to its nature as a contract, you know that it has a Get() method that returns a User, but you don't really care if that user was newed up in the method or if it was fetched from the database, or an API, you just care that your request for a user returned a user.
This is useful in Dependency Injection, where you inject an Interface rather than an actual implementation of something. In doing so, when running unit tests on your code, you can inject dummy dependencies that still fulfil the interface requirements (like just conjuring up a user) and ensuring that the code you actually want to test (your class) is working properly, without a dependency causing problems, say, a database connection going wrong and causing delays and errors in the tests in one run, but working the next.
@@Dojan5UserRepository interface
implementations:
SqlUserRepository, MongoUserRepositiry, PgSqlUserRepository
Thanxs for the video, I felt it was extremely clarifying and also I'm happy to see the comments because increasingly there are more developers becoming aware of this naming conventions for types. I would have liked you could elaborate more the "Never Pluralize" chapter, because there are some particular scenarios when you need to pluralize in addition to typed arrays, as for example an object of options (options: Options) => {...} or util types that require of pluralization like FindPaths, or whatever similar case. However I agree with the never pluralize rule explanation you did, but there are some edge cases where is more clear to pluralize the type. For the rest of the video, I completely agree as well.
Great video Matt !! Always a pleasure learning from a wizard 🧙
As a proud heathen, I'll say it must pronounced as "Route" not "Root"
😅
But King's english says "Root"
Must be.
@@KiwiCoke the king was a product of incest and pedophilia… probably shouldn’t be the standard for anything 😬😬😬
Rowte
The content that I would love to watch more! Thanks Matt😊
Awesome! Thank you Matt
Love your videos and also the way you present them. Thanks Matt
2:44 Thank you for this! My team have been doing this for a while and I've been trying to convince them to stop since I had the exact same thought as you
thanks for the video mate. great channel
Thanks for your work ❤
Thanks Matt, useful and concise 👌
Cool channel! Keep up, man, quality content!
thanks for sharing your wisdom Matt :)
thanks for clarify this which is what i was wondering all today.
Thanks for clearing out that the Hungarian notation is not a good convention in TS! Keep up the good work, Matt
Short, sweet, to the point. Good video :)
I often use IInterface or TType because they may interfere with React components as they might be similar e.g. component could be User and the interface for a user object may be IUser.
This happened to me today. I think I'd rather use prefixes for interfaces and types.
It is a great video. Thank you 🙏
Good stuff Matt, ur the goat 🎉
I like it. Especially things like TData, TError, etc. for improved readability.
For the last point: in terms of OOP design it may make sense to have an interface named IUser and a class named User which implements IUser. I don't think there's any other sensible way to name the interface in this scenario, but if you're not using classes, then the I prefix is definitely unnecessary.
wouldn't it be better to just name the interface User and name the implementation on what makes the user implementation different from other possible implementations of the interface, e.g. a Database interface with a MySqlDatabase class implementation, or just omitting the interface entirely, if possible? :-)
@@pieter-h I do that, too. I have Sensor as the interface, and then the type of sensor reflected in the implementation name.
You can name both: User. TS is able to recognize which one is the type and which one is the interface. You can even export these 2 together.
UserImpl?
You should always consider the existence of two or more implementers of your interface. What would make each implementation distinct? The latter would be reflected in the name of each implementation, but only the commonality in the interface name. E.g., IUser vs Reader, Editor, Administrator, Moderator, Commenter and maybe a DefaultUnknownUser if you need something completely generic to fallback to.
Very nice video. Another way of thinking about Route is that it is one entity indeed, but it exists in different states in multiple universes. That's what TS unions basically are; they "split" code flow into parallel versions of reality in compile-time (and only one version of such exists in runtime, of course)
Nice one, subscribed 😉
In my org (we use c# for back end primarily), we stick to the IInterface convention because 1. c#, 2. a lot of the times the implementation is named the same as the interface which causes confusion both for developer and compiler.
Other than that, I agree with you, especially in TS context
C# is a good point. There's no multiple inheritance of classes, just interfaces, you can't create "new" interfaces, and the MS standard (and thus much of the code you'll be using, like Enumerators, LINQ, and etc) uses the "I" prefix, which results in a number of pain points if you don't use the I standard.
Yes, that and in C++ interface is not a keyword. Interfaces are pure virtual classes.
same here for backend, but I ditched "I" in our react app because it doesn't seem to map well to front end hook stuff. Maybe I'll have another look and reconsider. That might be partly why I find it dizzying to keep switching to/from backend and web. ha.
Yeah for C# its the standard to prefix interfaces. Just to prevent naming collisions. Thats why we can have List and IList. In Java, its List for the interface and ArrayList for the implementation, because they don’t prefix they have to give things other names all the time.
Yeah, C# convention chose to prefix interfaces with 'I' to avoid conflicts with the basic/single/primary/reference implementation. So class User imlpements IUser.
In Java convention, the interface gets a regular/bare name so the implenting class has to adjust it's name to avoid conflicts. If you don't expect many implementations, the primary/reference implementation gets an "Impl" suffix. So class UserImpl implents the User interface.
I think the I-prefix for types and interfaces and T-prefix for generic types is the best way to do it as it's clearly distinguishable from other pascal case named types like React components, classes, etc.
Thanks Matt I needed this. I'm a TS beginner coding the backend of a forum with Express and named my interfaces commentsInterface, forumInterface... no need to add the "interface" word 😅
You get a prize for being the first person I've heard say "the King's English" this century.
I usually use the T prefix for type parameters if I want to give them a more verbose name so it doesn't shadow actual type definitions
"It's pronounced 'root' you heathens"
proceeds to pronounce it as 'rawt' (1:45) 😂
Great video as always Matt!
In some cases, prefixing interfaces with letter I makes sense - take react for example. "Post" would be a component and "IPost" would be an interface
Awesome short video
Great video! I guess for TS you can omit the I prefix for interfaces, since your IDE can show you that it is an interface. In C++ though, there is no interface keyword, but it is essentially a pure virtual class. Here I recommend the I prefix.
I saw the thumbnail, I thought you were gonna tell that we should use I for interfaces, and T for types. I was relieved to hear your thoughts about it
Oh wow, this TData, TError is so brilliant! I think I will change some of my code now...
Excellent video. I like the holdovers from the Java and Delphi days. I like to prefix "p" to function parameters, for example, " function searchByName(pName: string): TPerson[] { ... } ", that's because I want to use "name" as the sanitized value, for example, " ... { const name = pName.toRemoveInvalidChars().toLowerCase().trim() ... } ".
Great content as alwaya
The routes example was eye-opening
The prefix really helps when you import types and components. Say you have a Comment component and a Comment type. It's hell trying to import that as VSCode auto complete will get easily confused. Especially since the naming convention is the same
Why is it hell? Import will pull in both if they're in the same module, and if they're aren't that's just the usual import collision which is easy enough to handle.
In that specific example, if is likely to lead to a problem, I see which is more likely to be widely used and therefore the "default", and change either the component to CommentView or similar, or the type to CommentDetails or similar, assuming I don't have a better option for naming them. Certainly IComment would be completely wrong, as that implies that Comment implements IComment.
Could you go over points regarding using an ORM vs not using one? and when opting to not use an ORM. which tools would be helpful for connection pooling, migrations, caching, etc..
I’m totally fine with T for generic argument, R for generic return value, and K, V for key and value generic types. So function foo(arg: T): R is fine or Record where K : string | number | symbol
Good shit, agree with everything. Although I usually use "FooT" for generics instead of a "T" prefix.
one of the most helpful video about TS for our community)))
what about generic types - I think that you can use T and U, but if you have more - use normal name, please)
Awesome video as always! On the fun side did I hear 1:44 Uppercase ROUTE :D
we need a 5 hour long video/course with Matt speaking non-stop
Lately, I’ve started to use the I-prefix for interfaces in React, since then I won’t run into Chat the interface and Chat the component etc.
That couldn’t come up with a better example on the spot.
haha you know us so well, called me out on the pronunciation before i could think of typing a smartass comment :P great video!
whats your thoughts on typing the same thing for different contexts? Like `User`, where you might have a db Model type, a document type, and a typed api response?
Thanks
Ok, Ruts no Routs. Excelente contenido amigo!
Great tips! Do you have any recommendations for when the backend data type is the same as a React component type? In your example, Organization, but we also have a React component named that. Any thoughts? Thanks again for your work!
Sounds like you should rethink your component name, something like OrganizationDisplay, since "Organization" is easily understood as a data type, does not make a lot of sense to name a component that way, it also makes it hard to "guess" what the Organization component do, might be a table, a label, a form, no way to know by just glancing at the code
I use “I” prefix for interfaces as I only use an interface to describe classes. Usually variables are camel cased and types are pascal cased; so they are distinguishable. Classes are pascal cased and interfaces are as well; so I use “I” prefix to distinguish them
e.g.
class Organization implements IOrganization
I have a few opininons for these advices I want to share.
For pluralization, the true question is whether the type represent a unit or an aggregation of values. A Route between different possibilities denoted by the union is really only a single value at a time, a unit, while a list of routes is an aggregation of those values. Another case where it can help disambiguate the intention for a type is with object type, where a Vector or a User, while composite, represents a unit of correlated data, while an Options or Props object is a bag of named data that are not neccessarily very correlated.
For casing, it's more of a precision/theory about syntax highlighting than an opinion, the reason it starts highlighting your constant/variable as a type if a type of the same name exists is probably due to classes in JS. A class being technically a `let ClassName = a constructor function` (and a bit more, making them not just syntactic sugar), it is a variable, and in typescript classes also declare an interface type of the same name. I suspect that syntax highlighting for typescript assumes that a variable with the same name as a type is the type's class constructor and higlights it as such.
For type parameters, while I agree that giving more explicit names to type parameters is better than basic single letter names (Result better than Result or Result), just like function parameters, I think prefixing them with a T is not necessary or making the type parameter more legible. I'd compare it to prefixing function parameters with a p which would just end up making it anoying.
Lastly about knowing if a type is an interface or type alias, there is a value with the guarantees and different functionality you have with interfaces over type aliases, but yes, the prefix is unneccessary since we have tooling to inspect types and it usually tells which one it is. Programming in TS usually does not have the same experience as programming in C using a stock Vim decades ago, it's time to let go the habits of that time.
Every time you say the word "total" my mind immediately goes to Total Biscuit. Anyway, great content!
I almost always try to give full names for generics, however sometimes it doesn't make sense.
However I've not been prefixing generics. This lead to some awkward situations with name collisions and also just not being sure, so that's helpful.
For that initial example, a good example would be the type number. If a variable that stored a single number was of type numbers, people would automatically intuit that must be an array.
You'll take my IUserDetails from my cold dead hands.
Hi Matt, what do you recommend for naming types/interfaces on React functional components? By convention I have components as PascalCase and screens in lowercase, but then match the case/name exacty in my interfaces (where for data I would not - I'd follow your convention) I've seen a lot of ComponentNameProps for interface names, what do you think?
Yep, Props.
Is there any eslint rule to apply this awesome name convention?
“You can just hover to see the difference”
Well.. you can also refactor your I into a T with tools. Just go to definition, change keyword to type, refactor the name. Done.
You can also completely ignore types and just use interfaces in most cases.
When working with a dotnet + angular codebase I actually prefer prefixing interfaces (but not types) to keep a bit of consistency in naming between the two different languages.
I'm actually not getting that syntax highlight issue. const Route: Route highlights correctly for me in VSCode. I'm wondering though, even if it was a highlighting issue if CamelCase is the convention for components and classes and if I'm using the same convention for naming types, should I break convention or submit an issue to VSCode about incorrect highlighting? I mean, isn't that a bug if the IDE is highlighing a const or let as a type? Maybe this is another case for prefixing the type like TRoute? IDK, I'm a junior just trying to do the right thing.
The only thing I find difficult is when I have a type that has the same name as a component I have.
Let's say I have a component called Form, and it consists out of FormElements (also a component).
I have an API that returns json like so: { form: {name: "name", formElements: []} }
For this I create a response type called FormResponse.
But then the inner types for Form and for FormElement.
Usually I just call them Form, and FormElement. However, that sometimes gets confusing with the components, so then I call them FormType and FormElementType.
And sometimes you also have request types, so you have FormRequest and FormElementRequest.
Idk really.
using 'I' at the start of the name of an interface is standard practice in C#. even interfaces from the default .NET libraries use the prefix. i like to use it for clarity, so that i know that it's an interface at first glance.
it's not a bad practice, just different
What are your thoughts on using `I` as a prefix for `infer`ed types?
I am route.
I've started using TData with generics when there are multiple types like in your example.
One thing I do get stuck on is naming types when they are similar to their final variable names, still haven't figured out how to get around that yet. Particularly with React Contexts:
type AuthContext = {...}
const AuthContext // oops
in my current project, I have properties like this from a lot of my types: thisType, thatType, fooType etc., which basically is a string union on which "type" a certain object is. It's kind of confusing if I don't add a T before the type's name. (2nd reason: type name and component name is conflicting)
I've arrived to the same conclusion on C++... Pretty much exactly, except I put "T" at the end of a template parameter name. I never use plural, instead of "onions" I use "onion_list" or something similar. Types and functions CamelCase, data and objects snake_case. And I've dropped all prefixes.
If you use typescript class, how to prevent circular dependency?
If they are properties of each other?
I've been thinking about name collisions between react components and types, because both start with a capital. So far I've been abstained from hungarian notation, but I feel like it could be useful again. Idk which of types or components should get the prefix/suffix tho.
Just do `import * as React from "react";` and you're golden, now it's `React.Component`. No collisions.
I'm a C# dev and the IPrefix for interfaces is pretty much set in stone at this point.
However I quite like it since it has some benefits. The convention I commonly use is that (for instance) ISignal is the public part of the class Signal. The creator of that class can use all control methods while interface consumers can't. Having no 'I' in front of an interface would require me to find two names but even finding one is difficult enough.
Yeah, but in that context actually prefixing interfaces with an "I" actually makes sense because you want to differentiate classes and interfaces (I also used to do it back when I was doing C#).
In TS though, the differences between types and interfaces are so subtle that I don't really see the benefit of having a prefix.
@@driden1987 I also preffer to name the interface IArticle when working with React. I would have a component named "Article", and I would need that article type everywhere. I always use the quick fix suggestion from vscode when something needs to be imported. So it will suggest 2 imports for the same thing and I don't like that. I want to avoid confusions. ☺️
@@driden1987 But why do you want differentiate classes and interfaces? This convention doesn't make sense even in C#. Java for example doesn't enforce this.
@@ex-xg5hh class User implements ?User? {}
@@ex-xg5hh I think it mostly comes from Microsoft's way of doing things.
I always prefix interfaces with I, types with T and enums with E. Also, full names in generics only. Can't stop me 😎
Yeah it just doesn’t make sense to me without the prefixes. Particularly in NestJS, where OOP is heavily used.
it is better to use T, I and E prefixes, because it can significantly reduce amount of type names. And also you can nicely group these types with each other.
Agree with everything here.
I use the I* prefix for both `type`s and `interface`s. After all, they are the same thing in TS - just different ways to write it.
As for why, well it's mostly because I'm lazy and want to differentiate between constructor types and my defined types, without having to think of a new, non conflicting name.
Hello Matt, nice beginners course. May I ask you a question about a piece of code found on the typescript handbook page. Under chapter "Template Literal Types" they have a piece of sample code whereby the declare a function "makeWatchedObject". Could you make a video about an implementation if this function? It looks very interesting to me.
Could you ask in my Discord? mattpocock.com/discord
What would be the appropriate name for a type that represents an array of objects received in response, but where the (react) components only use individual objects, e.g. after mapping? Typically, I use the type "Items = {...}[]" for the array and "type Item = Items[number]" within the component. Is there a more optimal solution?
type Item = {...}
type Items = Item[]
1:44 What did you say? You heathen 😁
Type is a class right? So I would name the interface to that type the exact same thing, but with an I in front. I don't generally use a prefix for classes themselves, as the Capitalization and the location it's used is more than enough, if you don't also have an IDE that color marks it. However, it can be nice to call your interfaces the exact same thing as the class, but with an I in front, to easily see where it belongs.
big agree
I think as a beginner going through the process of getting used to TypeScript, using TUser and IOrganization is helpful so that you start getting used to these new variables showing up in your code and immediately seeing that "oh, that's a big T as the first letter, that means it's a type! And that thing with the I is an interface!" But once your brain adjusts and can tell what a thing is by context instead of literally spelling it out, then you should drop those extra letters.
I agree. It’s cool to see that avoiding I and T is accepted and look forward to remove them from my code but I’m not really sure that doing so would help readability.
Well type and interface do not differ that much in Typescript. You can pretty much always use them interchangeably. The difference is noticeable only when you are creating the type/interface
@@theseangle Sorry, it's not necessarily about knowing exactly which kind of typescript thing is in the code, it's about being able to see that the unexpected thing in your code is a typescript thing. For beginners, the code looks odd, and the clear visual cue that the odd bit is for typescript helps a learner get used to it faster.
In typescript there are clear type contexts and value contexts, you can't confuse a type with a value.
thanks
The I prefix is so that when you import "User" object you don't confuse it with 'IUser"..
(can alsi cause issues while importing..)
Is prefixing interfaces with I a Java thing? I only know it from C#.
We prefix interfaces with I on classes, so
class MyClass implements IMyClass
Wasn't a fan at first but the convention makes it easy to find the class instance or the interface
I'm using IUser because it conflict with User component in React and vscode get confused sometime if I dont make it clear.
You heathens!!...yesss, set them straight Matt!😂
So If I have an array list of something like user list, then the name for this will be "userList" right?
Really appreciate your typescript tip videos. And I’ll definitely start prefixing my type params for generics.
I agree, it’s more readable this way and I can easily know what’s going on if I’m away from the project - thanks 👍🏽
The prefix stuff you said comes "from the Java days" is actually called "hungarian notation" and much older than Java.
The Interface "I"-Prefix is one of those things that are deeply engraved in our company guidelines. I don't really feel strongly about the rule itself - but I aggree, that it's kinda pointless in TS. In C# however it is often necessary because often you have Interfaces that exactly represent an existing class. I hate it - but sadly in C# it is required to be able to mock those classes in unittests.
You're right. It seems this is more like a naming practice was bring from mainly strong typed oriented to objects languages (such as C# and Java) to TS, that eventually got adopted by some people, but yeah, it's kinda pointless in TS.
how to make the name refactor without actual to use the find and replace like the wat it is shown on the video?
What are your thoughts about Typescript annotations using JSDoc? I've been learning TS on a slow pace so I only tried using JSDoc annotation in my recent sveltekit project. I am quite amaze, but I am not convinced that I should use TS immediately.
As someone who's been trying to use jsdoc as a soft replacement for TS it just doesn't hold up. It's not simple to use while at the same time being tough to get the same effectfor the same effort as TS
imho, just bite the bullet and use TS immediately, and in a month you'll be one of us and wonder why on earth you considered anything else.
(Just as a sidenote, when interviewing I would never hire someone who had doubts about whether to use TS)
even java people dont do the "I" thing anymore 😂 but i see it used a lot in c# still. i think we got rid of hungarian notation for a reason. express intent not types.
Someone should write a set of eslint rules that enforces these tips. they're great.
One curve ball for you. You have a class and an interface that the class implement. What do you call the interface? Since both the class name and the interface are in Pascal I think calling the interface Ixxx is a valid? Please let me know if there is a better way to do that. Thanks! Love your content, man. Keep the videos coming! ❤
Which are public (or, more public)? If it's both, why are they separate?
If it's just so you can mock it, you don't in general need to have an interface for that in TS. If it's so you can have a general interface that people use and a default implementation that should only be used as "const foo: IFoo = new Foo()", instead expose a "function createFoo(): IFoo", it's much more flexible. Most of the time you don't even need classes at that point, just return an object!
Otherwise it doesn't really matter what you call the private one, but the public one should be the "simpler" name. You can call the private class FooImpl if you're really stuck.
I would name "IUser" as "Userable" and "IOrganization" as "Organizationable". 😎
Doesn't make much sense. Interfaces in TypeScript are not entirely like your traditional Java-like interfaces. Ideally you'd use some struct type for objects like User, but alas there are none; other than a "class" which unnecessarily represents more than just a simple JavaScript object.
If the idea is to use interfaces for implementation details, they should be small and composable. Name the interfaces after the fields or context they provide, so you don't have to come up with nonsense words.
This is also what Rust does with traits. You don't have to suffix "-able" on every interface.
type User = { name: string; }
type Organization = { organization: string; }
type OrganizationMember = User & Organization;
@@dealloc Thanks for pointing that out. Until this point in time, I was not thinking about composability when naming interfaces. Maybe because I rarely composed any types in my projects. Just appending "-able" worked for me. Simple. 😅
Just add I. It's fine. You rarely ever change an interface to a type as interfaces contains methods.
What you did here look likes Java! Yes, prefixing `I` is from C#.
I use "root" for specific roadways, and "raot" for derived paths like in code.
Objection: Flags are plural. If your union represents flags, then multiple of them can be set and you always pass around a collection of flags which is not necessary an array, as flags can also be OR'ed bits.
As for the I-prefix This is done in case you want to be able to have both, a type and an interface of the same name, which you cannot if they share a common name space. In other languages it's usually interface and class, as you may want to have a List interface but you may also want to have a class named List, so the interface is named IList. You may think that's silly but to be honest, every argument you bring up against that I is equally an argument against prefixing type parameters with T, which I see as equally silly.