Interfaces in TypeScript

By Dawid on (tags: interface, TypeScript, categories: code)

In TypeScript interfaces are used to descript a type. Classes and functions are used to implement behaviour while interfaces are providing information's about shape of the data. All of the type information’s are removed from TypeScript program during compilation there is no runtime overhead and we can freely add type data.

To be honest with you interfaces are like Swiss army knife. We can use them in following cases:

  • describing an object
  • describing an indexable object
  • ensuring class instance shape
  • ensuring the static shape of a class or constructor object

Describing object

   1: interface ICarOptions {
   2:     mark: string,
   3:     model: string
   4:     color?: string
   5: }
   6:  
   7: function createCar(settings: ICarOptions) {
   8:     ...
   9: }

Note the use of the ? symbol after color - this marks a member as being optional. In the compiled JavaScript you will not see any information’s about defined interface as those are only compile time construct and have no effect on the generated code.

Describing and Indexable object

I thing that all of use used and object in JavaScript – {} – to map from set of strings to set of values. We can use interface here when those values are of the same type. This will describe that indexing  into an object always produce values of a certain type.

Take a look at this example:

   1: interface CarMap {
   2:     [model: string]: Car;
   3: }
   4:  
   5: var map: CarMap = {};
   6: map["audi"] = new Car();
   7: var c = map["audi"]

Thanks to the interfaces you can be sure that in variable “c” will be stored object of Car.


Ensuring class instance shape

Lets imagine that we have following interface describing car:

   1: ICar {
   2:     start(): void;
   3:     stop(): void;
   4: }

Now we can use to to describe car object:

   1: class Car implements ICar {
   2:     color: string;
   3:     engine: Engine;
   4:  
   5:     constructor(color: string) {
   6:         this.color = color;
   7:         this.engine = new Engine();
   8:     }
   9:  
  10:     start(): void {
  11:         this.engine.startEngine();
  12:     };
  13:  
  14:     stop(): void {
  15:         this.engine.stopEngine();
  16:         colsole.log("engine stoped");
  17:     };
  18:  
  19:  
  20: }

Ensuring shape of an object

Lets assume that we want to describe return type of an function. First we need to define an interface:

   1: interface IPoint {
   2:     x: number;
   3:     y: number;
   4: }

Now we can define function like that:

   1: createPoint(firstCoordinate: number, secondCoordinate: number): IPoint {
   2:     return { x: firstCoordinate, y: secondCoordinate } as IPoint;
   3: }

Extending interface

There is one more nice thing about interfaces in TypeScript – they can be extended. It’s quite simple:

   1: interface Shape {
   2:     color: string;
   3: }
   4:  
   5: interface Square extends Shape {
   6:     sideLength: number;
   7: }
   8:  
   9: let square = <Square>{};
  10: square.color = "red";
  11: square.sideLength = 20;