Hey TypeScript, where’s my I-prefixed interface!

Jonathan Yee
5 min readAug 25, 2017

--

Update: found some caveats from my further usage. The main points still holds true imo.

I work in a DotNet shop (that should give you a hint where this is going). Recently we started using Angular. One of the discussions was around TypeScript’s Interface naming convention.

Naturally, most of us wanted to continue with C#’s I-prefixed Interface although the TypeScript project itself had its own opinions and so did the Angular styleguide.

Left: TypeScript guide. Right: Angular’s guide

The TypeScript guideline was written for the project itself and does not stretch out to the wider community. Same goes for the Angular page which is just a consideration.

With that I’m going to just do what I’m used to as a C# guy.

And yes it does make sense to most of us. But it has made me question: Why does TypeScript not recommend it yet C#(think Resharper) does?

Grok on Sight

Let’s see the case of C#:

C# class with an interface and class…which is which?

To implement an interface or inherit a class, the keyword : is used for both. Now there is no way we can figure out by examining that which is of what type. So in C# I-prefix would help to identify quickly its types.

Now let’s have a look at TypeScript:

TypeScript class with an interface and class..make an educated guess.

With knowledge that, extends is used for inheritance and implements is used for contracting, we can very well guess which is our class and interface.

Declaring the Type

For declaring a variable in C#, it does make a difference if it’s assigned as an interface or a class when it’s used against a method that is expecting a particular type.

c# strict static language at its best

Not so much in TypeScript. Let’s have a look (Apologies if it´s too contrived):

TypeScript is static but dynamic

What this points out is Typescript favours the mould of a class rather than its concrete type. In the end interfaces don’t matter in JavaScript as it holds true to the nature of its dynamic language derivative.

Behold, you could actually use implements on a concrete class as an Interface(?)!

TypeScript using a class as an interface!

Caveat in using class as implements: doesn’t work when your class has private properties (which in almost all cases do). See https://github.com/Microsoft/TypeScript/issues/471.

Although TypeScript allows this (unofficially), it does not make much sense. If you do want to, use a proper Interface. Although I could see the benefits in being DRY if TypeScript would allow it.

I’m convinced I don’t need the I-prefix

Ok, so I went and played around with it more…

Hey Typesrcipt, where’s my interface!

Oh great - now back to I-prefix again.

Wait! There is a deeper problem here. The problem isn’t because we can’t have types with the same name. It’s not knowing how to give meaningful names. Yup, this sounds like a topic for a whole other post but it warrants as a caution not to use I-prefix.

We have been taught by the archaic wisdom of Hungarian Notation that to make things easier to read we need to emphasise it. Do we really have to? Shouldn’t the name describe its intent and speak of its characteristics? We know a firstName will be a string. We know counter is a number . What makes Interfaces any different?

We need to understand the intent of Interfaces in OO.

The term interface is often used to define an abstract type that contains no data or code, but defines behaviors as method signatures.

If they are a conceptual idea that can be used to describe numerous concrete entities, then why don’t we name our Interfaces that way? Generic and conceptually.

We’ll use earlier examples to reiterate the point above. Vehicle would describe the concept of an object that transports. Car would be a concrete creation of a Vehicle. And so would a Motorbike or a Tesla.

How about the example on Car vs OldJunk? Both OldJunk and RaceCar have the characteristics of a car. It’s all in the context of our objects. What are our concrete objects and how can we relate our objects to each other conceptually.

What if Car was a concrete class? Do we then rename the interface to ICar? No, not if we want the Interface to abstract the similar behaviours. Maybe the question we need to ask is, “Does Car clearly define the implementation?” We need to be specific with how we describe our classes.

Conclusion

So, it seems all roads point to not having I-prefix. But does that mean I’ll be using it in my team? Maybe not. At the end of the day, what ever guidelines or conventions we use they need to help the productivity of the team. Moreso understand why we do what we do in terms of naming our Interfaces.

--

--

Jonathan Yee

Faith bound. Once suffered from Impostor syndrome. Now unafraid to lack. I share now and then my thoughts as a programmer and as a christian.