About a month ago, Microsoft released the 0.9 version of TypeScript. Originally released in October 2012, the language has come a long way and one of its most requested and recent additions is generics. You may find yourself asking, “When the heck am I going to use generics in JavaScript?” I had the same question. The answer is all the time!!

Even If You Don’t Care

Even if you don’t care about generics yourself, you’ll start to get benefits from the community. For example, if you use the DefinitelyTyped definitions, those are being upgraded to 0.9 versions and generics are popping up. This means that if you use one of these definitions inside of Visual Studio, you’ll get all the goodness of IntelliSense.

Prior to generics, you’d get information about a type and it would say: “any”. Lovely. How descriptive. Now, you might get a description that says, “superEntity”.

Array<T>

var blah = new Array<T>();

var myArray = MyModel[];

Interfaces

module TestModule { export interface IDataService<T> { getAll(): Array<T>; save(item: T); } export class Entity { message: string; id: number; } export class EntityService implements IDataService<Entity> { constructor() { } getAll(): Array<Entity> { return new Array<Entity>(); } save(item: Entity) { } } }

One of the most common uses you’ll have for generics is when you want to create an array of a specific type. Of course, in JavaScript, the elements of an array don’t need to be the same type. In TypeScript world, however, types are king and the same goes for typed arrays. Now we can declare an array of T such as:The next time we try to use that array, by default we’ll get all sorts of wonderful toys to play with. In Visual Studio, we’ll get IntelliSense telling us exactly what type of array we’ve got and, because it knows what type the array is supposed to be, if you try to stuff something in there that isn’t of that type, you’ll get a compiler error (unless the signature of the other type has the same properties – see below). This was already sort-of in TypeScript before because you could define an array like this:That worked in earlier versions of TypeScript – if you try that now, you’ll get a compiler error that asks you to do the Array version.The interface is a great place to use generics. Let’s create a base interface that has a couple of CRUD methods on it:This allows us to write our data service specifically to the Entity type and get information about this type as we write it. Here’s what it looks like in the editor:

See? By using the generic interface, our implementation was forced into using all the right types. To make our life even easier, we’re given the IntelliSense on the type in question. Isn’t laziness awesome?

Continuing, let’s say you’ve got some code that actually takes a service as a parameter. This happens a lot in modern JavaScript especially with frameworks like AngularJS where controllers and other MVC-ish patterns use dependency injection.

module TestModule { export interface IDataService<T> { getAll(): Array<T>; save(item: T); } export class Entity { message: string; id: number; } export class NotMyEntity { title: string; description: string; } // Notice this has the same structure of the original Entity export class AnotherEntity { message: string; id: number; } export class EntityController { constructor(public service: IDataService<Entity>) { } save(item: Entity) { var obj = new NotMyEntity(); this.service.save(obj); var structuredObj = new AnotherEntity(); this.service.save(structuredObj); } } export class NotMyEntityController { constructor(public notMyService: IDataService<NotMyEntity>) { } save(item: NotMyEntity) { this.notMyService.save(item); } } }

We define a generic interface that’s implemented somewhere else (perhaps the in first code block above). Our controller (NotMyEntityController) is dependent on a service that implements this interface for a specific data type, in this case NotMyEntity. Line 41 is where that dependency is declared. We use the service in the save method and all’s good.

But take a look at the EntityController, specifically the save method.