Object Oriented Programming with TypeScript Tutorial (JavaScript OOP)

I was excited when I heard about TypeScript because I love typed variables, interfaces, calling super in your methods and extending classes without all the mess of JavaScript’s native prototype. I know there is a lot of haters already of TypeScript and I haven’t made up my mind yet if TypeScript is awesome or not. Right now I am just playing around and wanted to share. If you don’t have TypeScript installed and you are using a mac. You can check out how I did it: Installing TypeScript on a Mac

One cool thing about TypeScript compiler is how you can import other classes that are required by using <reference path/>. This is done by: ///<reference path=’path/to/Class.ts’/> . TypeScript’s compiler will concatenate the files into one file and remove all comments.

This is not a tutorial but more of an example on how to setup some classes in TypeScript. Below is our Main class that makes use of our Car and Truck class. I am not going to go into details about each class. You can download the classes and folder structure below.

///<reference path='components/vehicles/Car.ts'/>
///<reference path='components/vehicles/Truck.ts'/>

class Main {

    private _compact:Car;
	private _pickup:Truck;

    constructor()
    {
        this._compact = new Car(21, 18);
        this._compact.changeGear();
        this._compact.useAccessory();

        this._pickup = new Truck(16, 23);
        this._pickup.changeGear();
        this._pickup.useAccessory();

        this._compact.soundSystem.turnOn();
        this._compact.soundSystem.playSelection(2);
        this._pickup.soundSystem.turnOn();

        this._compact.drive();
        this._pickup.drive();
    }

}

Here we have our Car class and below that we have the Truck class they both extends the Vehicle class. Take note of the Tire class where we pass in an Static property that is located in the TireType class. Also look at “this.soundSystem”. This property accepts a interface class called IAudible which CDPlayer implements.

///<reference path='Vehicle.ts'/>
///<reference path='../accessories/Tire.ts'/>
///<reference path='../../constants/TireType.ts'/>
///<reference path='../accessories/soundsystems/CDPlayer.ts'/>

class Car extends Vehicle {

    private _tires:Tire;

    constructor(mpg:number, fuel:number)
    {
        super(mpg, fuel);

        this.name = "Car";

        this._tires = new Tire(TireType.HIGH_PERFORMANCE);
        this.soundSystem = new CDPlayer();

        console.log(this.name, "has", this._tires.getType(), "tires");
    }

    public useAccessory():void
    {
        this.openSunroof();
    }

    private openSunroof():void
    {
        console.log(this.name, "opened sunroof");
    }

}

Our Truck class is similar to our Car class but take note of the “this.soundSystem” property where a Radio class is used. The Radio class also implements the IAudible interface.

///<reference path='Vehicle.ts'/>
///<reference path='../accessories/Tire.ts'/>
///<reference path='../../constants/TireType.ts'/>
///<reference path='../accessories/soundsystems/Radio.ts'/>

class Truck extends Vehicle {

    private _tires:Tire;

    constructor(mpg:number, fuel:number)
    {
        super(mpg, fuel);

        this.name = "Truck";

        this._tires = new Tire(TireType.SNOW);
        this.soundSystem = new Radio();

        console.log(this.name, "has", this._tires.getType(), "tires");
    }

    public useAccessory():void
    {
        super.useAccessory();
        this.lowerTailgate();
    }

    private lowerTailgate():void
    {
        console.log(this.name, "lowered tailgate");
    }

}

The TireType is simple class that has static constants. I like using classes like this in my applications because it is easy to know what types are available to you. These classes are very useful when you have an IDE that has code intelligence.

class TireType {

    static SNOW:string = "snow";
    static HIGH_PERFORMANCE:string = "highPerformance";
    static ECONOMICAL:string = "economical";

}

The Tire class just sets the type description from what was passed into the constructor.

///<reference path='../../constants/TireType.ts'/>

class Tire {

    private _type:string;

    constructor(tire:string)
    {
        switch (tire) {
            case TireType.SNOW :
                this._type = "storm-ready snow";
                break;
            case TireType.HIGH_PERFORMANCE :
                this._type = "high-performance radial";
                break;
            case TireType.ECONOMICAL :
            default :
               this._type = "economical bias-ply";
        }
    }

    public getType():string
    {
        return this._type;
    }

    public setType(tire:string):void
    {
        this._type = tire;
    }

}

The Vehicle class is the base class for the Car and Truck class. I love how you can set default value right in the function parameter. In this case we have default values in our constructor.

///<reference path='../../interfaces/IAudible.ts'/>

class Vehicle {

    private _gasMileage:number;
    private _fuelAvailable:number;
    private _milesTraveled:number;
    private _moving:bool = false;

    public name:string;
    public soundSystem:IAudible;

    constructor(mpg:number=21, fuel:number=18.5)
    {
        this._gasMileage = mpg;
        this._fuelAvailable = fuel;
        this._milesTraveled = 0;
    }

    public useAccessory():void
    {
        console.log(this.name, "turned on lights");
    }

    public changeGear():void
    {
        console.log(this.name, "changed gear");
    }

    public drive():void
    {
        this._fuelAvailable--;
        this._milesTraveled += this._gasMileage;

        if (this._fuelAvailable > 0) {
            this.drive();
        } else {
            console.log("The", this.name, "has a gas mileage of", this._gasMileage, "and traveled", this._milesTraveled, "miles.");
        }
    }

    public getGasMileage():number
    {
        return this._gasMileage;
    }

    public setGasMileage(mpg:number):void
    {
        this._gasMileage = mpg;
    }

    public getFuelAvailable():number
    {
        return this._fuelAvailable;
    }

    public setFuelAvailable(fuel:number):void
    {
        this._fuelAvailable = fuel;
    }

    public getMilesTraveled():number
    {
        return this._milesTraveled;
    }

}

The IAudible interface class allows us to swap in a CDPlayer or Radio class to our vehicles and the vehicle class knows what methods and properties are available. We could easly add a TapeDeck or an EightTrackPlayer and we would only have to change one line in our code.

interface IAudible
{
    isPlaying:bool;
    turnOn():void;
    playSelection(preset:number):void;
    turnOff():void;
}

The CDPlayer implements the IAudible interface class.

///<reference path='../../../interfaces/IAudible.ts'/>

class CDPlayer implements IAudible {

    public isPlaying:bool;

    constructor()
    {
        this.isPlaying = false;
    }

    public turnOn():void
    {
        console.log("cd player on");
        this.isPlaying = true;
    }

    public playSelection(preset:number):void
    {
        console.log("cd player selection play: track", preset);
    }

    public turnOff():void
    {
        console.log("cd player off");
        this.isPlaying = false;
    }

    public eject():void
    {
        console.log("cd player eject");
    }

}

The Radio implements the IAudible interface class.

///<reference path='../../../interfaces/IAudible.ts'/>

class Radio implements IAudible {

    public isPlaying:bool;

    constructor()
    {
        this.isPlaying = false;
    }

    public turnOn():void
    {
        console.log("radio on");
        this.isPlaying = false;
    }

    public playSelection(preset:number):void
    {
        console.log("radio selection play: channel preset", preset);
    }

    public turnOff():void
    {
        console.log("radio off");
        this.isPlaying = false;
    }

}

To compile all the classes into one file I use a terminal command on the mac. Here is the command:

tsc Main.ts -out ../bin/main.js

That will save a javascript file called main.js into a folder called bin one directory up from the Main.ts file.

One thing I don’t like about TypeScript is the lowercase types (string, number, bool, etc.) I would prefer them to be uppercase(String, Number, Boolean, etc.) because they do represent Classes. Since Microsoft developed it, I guess they wanted to add some of there C Sharp syntax.

Also if you like this tutorial please provide a link back to this page or my site.

16 Responses to “Object Oriented Programming with TypeScript Tutorial (JavaScript OOP)”

  1. WOW!! This was SUPER helpful!!

    Thank you so much!

  2. Thank you so much for this detailed sample. This is exactly what I was look for.

  3. I don’t get what are the main differences between java and type script .

    need some information regarding to the working of type script and
    what are the key features of type script

    how it works
    Mainly how it reduces the CODE

    • The main difference I see is how easy it is to create classes that can extend other classes. Then you are just writing JavaScript after that.

      class Truck extends Vehicle {
      //Now write normal JavaScript
      }

      You also don’t have to type out prototype on all your class functions which makes you source code smaller and cleaner to read.

      TypeScript is not a new language it just adds some conventions to JavaScript like how to create a class and the ability to add types to your variables and functions. This will help in error checking and refactoring when you have an IDE that supports TypeScript.

      You don’t need to use types such as (private, :number, :void, etc) but these will help with code completion with an IDE like WebStorm 6 or Visual Studio.

      Download the example code and compare the typescript code to the outputted JavaScript code.

  4. Thank you Robert ….

    It help me a lot…

  5. Can u provide me a a seminar report on Type script…

    it can help me in my studies…

  6. This page is excellent. Everything I pump into google relating to my typescript woes comes back here like an old friend. Thanks Robert.

    I have done almost what you have done, but used modules as package names.

    module com.codebelt.robert
    {
    export class Vehicle extends FooBar()
    }

    This is causing me all kinds of problems. If I am reading this correctly, there is no need for modules in this way. I can package my classes into individual TS simply reference them with the /// ?

    • Hey, thanks for the feedback.

      This is true you can have all your classes as single TS files and just reference them with ///<reference path=’folder/MyClass.ts’/>. Then type “tsc –out main.js Main.ts” which would be your top level class (Main.ts) and it will concatenate all your TypeScript files that are referenced in your classes into a single JavaScript file (main.js). Check out my HTML5 Canvas Ad with TypeScript Tutorial and download the example files.

      Sounds like there is going to be a lot of changes with TypeScript version 0.9.0. I am hoping they changed how modules are imported/referenced.

      • Finally have time to start looking through you website typescript articles. Sorry if I spam you in advance! I refactored my project to use your structure but I am getting problems with “this” scoping. For example I would get an error that window.turnOn does not exist. Therefor this appears to not reference the car but the window. I have no idea why this occurs but it appears to have something to do with lambda =>. As I have just realised during this post, I am using a global setInterval function to start the car. Thus turnOn becomes window.turnOn……. And does not refer to the car class method. I currently do not understand scope here.

  7. Awesome!

    The syntax is closer to Java than C# with keywords like ‘extends’ and ‘implements’. I worked with Script# and Saltarelle (C# to Javascript translators) and would like to know if there are any ways to translate C# to typescript.

    Thanks Robert!

    • I never new about Script# and Saltarelle but I don’t know if there is a compiler from C# to TypeScript. The syntax is very close to ActionScript 3 and that is why I like it.

  8. Would be awesome if you could write a new tutorial or add a section that the describes the whole build process. We want to compile our project into one JS file yes, but we also want to minify that file and have a working source map to go with the minified file. Moreover, we want a declaration file. This is requirements all serious programmers should have. Yet I keep reading tutorials all over internet covering all kinds of topics yet only describing the first few baby steps one need to take.

    Making the compiler output one single file with his source map and create a declaration file can be done from the GUI in latest Visual Studio. The tuff problem is to minify the file. How that affects the source map file, I don’t know.

    Thank you for sharing!

  9. siddjain Says:
    July 12, 2014 at 12:44 pm

    if you want to modify your csproj to create a single js file as part of build process (rather than running tsc.exe), insert following code in csproj file:
    app.js
    i got this tip from http://stackoverflow.com/questions/15864584/what-are-the-typescript-project-build-configuration-options

    i also inserted this code in the csproj to nuke out all the old js files before every build:

    del ..\*.js

    i also set this to false in debug mode as i don’t know what use it is:
    false

Leave a Reply