100 Days of TypeScript (Day 6)

On day 5, we looked at how to implement interfaces to say what behaviour a class can have. I said, at the end, that we were moving into the territory of doing inheritance. Today, we are going to look at how we can implement interfaces, inherit from classes and a whole lot more.

What is inheritance?

If you have never worked with an Object Oriented language before, the concept of inheritance might seem a little odd at first but it’s actually pretty straight forward. To explain inheritance, I am going to go back to an old favourite of mine, the guitar. I am going to demonstrate with a “pseudo class” structure, how to use inheritance. (A pseudo-class is one that demonstrates a class, but isn’t written in any particular language). To start with, I am going to look at the properties that a guitar might have.

  • Necks (typically one, but guitarists such as Jimmy Page sometimes used guitars with more than one neck)
    • A neck may have frets
  • Strings
  • Pickups (for electric guitars)
  • Pickup selector (for electric guitars)
  • Volume controls (for electric guitars)
  • Tone controls (for electric guitars)
  • A bridge (the bit that the strings go into in the body of the guitar)
  • Strap connectors
  • A body
  • A manufacturer
  • A make
  • Serial number
  • Sound hole (for acoustic / electro-acoustic guitars)
  • Headstock (the bit at the top of most guitars)
  • Tuners

That’s not an exhaustive list of all of the things that we can use to make a guitar, but it gives us a good starting point. Before I start creating my classes, I need to decide what is common and what is specialised; in other words, anything that all guitars share is a common feature, and things that are specific to a particular type of guitar are specialised. Anything that is common goes into something we call a base class; a base class is something we will inherit from that has properties and behaviours that are shared.

It is very tempting to jump in and say that the starting point here is a guitar, but I am going to take a step back. While I listed properties for a guitar, it is important to remember that a guitar belongs to a family of things we call musical instruments and there are certain features of a guitar that are common across all commercial musical instruments; if I were writing an application for a music shop, I would want to start with those features as the base for my guitars.

Musical Instruments representing the inheritance chain; the instruments are a piano, an electric bass guitar, an electric guitar and a violin with bow.
Musical Instruments as hierarchies

I will start with a MusicalInstrument pseudo class and put the features in there that are common.

Class MusicalInstrument
    Manufacturer
    Make
    SerialNumber
End Class

You might be surprised to see that I haven’t said what type of musical instrument it is that we are dealing with in there. The reason I haven’t done that is down to inheritance; I am going to use inheritance to say what type of instrument it is that I am dealing with so if I wanted to have a Piano class, I might look at that as being a type of Keyboard, which is a type of MusicalInstrument. This would give me something like this.

Class Keyboard InheritsFrom MusicalInstrument
    ... Features common to all keyboard type instruments
End Class

Class Piano InheritsFrom Keyboard
    ... Features that are specific to a piano
End Class

Going back to the guitar scenario, I might want to create my hierarchy like this.

Class Guitar InheritsFrom MusicalInstrument
    Neck
    Headstock
    Tuners
End Class

Class AcounsticGuitar InheritsFrom Guitar
    SoundHole
End Class

Class ElectricGuitar InheritsFrom Guitar
    Pickups
    VolumeControl
    ToneControls
End Class

I’m not going to add every property to these classes, but this should give you an idea as to what the inheritance chain should look like. What we see in all of this is that inheritance is about creating an object from a hierarchy.

Class inheritance with TypeScript

On day 5, I demonstrated how I can use implements to “inherit” from an interface (technically, we call this implementation rather than inheritance but people sometimes think of interface implementation as inheritance). I am now going to demonstrate how to inherit from classes. To make this interesting, I am going to start with the same validation interface that I implemented in the last post.

interface Validate {
  IsValid(): boolean;
}

If you remember, the last post demonstrated the minimum length validation and maximum length validation but there was code that was repeated between the two classes. What I want to do is create a base class that does all that is necessary for the common code. I am going to start with this code.

class LengthValidationBase implements Validate {
  constructor(protected text: string, protected length: number) {}
  IsValid(): boolean {
  }
}

This code will not compile because IsValid doesn’t return anything. I have two choices here. I can either return a default value or I can use “tricks” to avoid returning the value here. The trick that I am going to use is to make this class something called an abstract class. What this means is that this class cannot be created on its own; it must be inherited from, and the inherited classes can be instantiated.

By creating an abstract class, I am able to create an abstract method. What this is, is a piece of code that, effectively, says “I am not going to give you an implementation here, but anything that inherits from me must add its own implementation.” Unsurprisingly, the keyword to make a class or method abstract is, well it’s abstract. With this, my code now looks like this.

abstract class LengthValidationBase implements Validate {
  constructor(protected text: string, protected length: number) {}
  IsValid(): boolean {
    return this.CheckForValidity();
  }

  public Debug() {
      console.log(`Checking whether the length check of ${this.length} for ${this.text} is valid returns ${this.CheckForValidity()}`);
  }

  protected abstract CheckForValidity(): boolean;
}

There are a few things in my class here that I want to talk about. Let’s start with the constructor. In an earlier post, I talked about how I can declare class-level variables directly in the constructor signature. This is one of those really great features that TypeScript gives us that you won’t see in languages like C#. What we haven’t seen before, though, is this funny protected keyword. What does this mean?

If I want something to be visible only inside the class, I mark a method of field as private. This means that I cannot see this variable/method from outside the class. If I inherit from the class, I still can’t see that variable. If you are thinking that I need to see the values in text and length in my derived class (when we inherit from a class, we say that we have derived from the class), you would be correct. The way that we say that a method or function cannot be seen from outside the class, but can be seen from a derived class is to use the protected keyword.

The CheckForValidity method is interesting. This is an abstract method that I am going to call from the IsValid method, giving us the boolean return value that IsValid is expecting. You can see that this does not actually do anything – we can think of this as being a signature or contract that says “when you inherit from me, you must supply an implementation for this method”.

Note: You can only add abstract methods inside abstract classes. If your class isn’t marked as abstract, then you can’t create abstract methods in there.

Here’s a quick question. Do you think I can create a private abstract method? The answer to this is no, if I tried to do this, TypeScript would tell me that I cannot create a private abstract method. The message I would get is The “private” modifier cannot be used with the “abstract” modifier. When you think about it, this makes perfect sense. A private method cannot be seen outside the class, but an abstract method says that the code must be added in an inherited class.

Something you might be wondering about. Why have I added a Debug method? It’s not described in our interface, so why have I added one? I wanted to provide the ability to write out debug information about what the class is doing and, as the ability to debug doesn’t have anything to do with the validation interface. By using a backtick ` instead of an apostrophe ' in the console log, I am able to do something called string interpolation. This is the funny-looking syntax in the string where the values inside ${} are printed out directly.

Let’s revisit our minimum and maximum length validation. By using inheritance, I move from this.

class MinimumLengthValidation implements Validate {
    constructor(private text: string, private minimumLength: number) {}
    IsValid(): boolean {
        return this.text.length >= this.minimumLength;
    }
}

class MaximumLengthValidation implements Validate {
    constructor(private text: string, private maximumLength: number) {}
    IsValid(): boolean {
        return this.text.length <= this.maximumLength;
    }
}

to

class MaximumLengthValidation extends LengthValidationBase {
  protected CheckForValidity(): boolean {
    return this.text.length <= this.length;
  }
}

class MinimumLengthValidation extends LengthValidationBase {
  protected CheckForValidity(): boolean {
    return this.text.length >= this.length;
  }
}

It may not seem like I have removed a lot of code, but that’s not the main reason for doing inheritance. The main reason for inheritance is to remove code duplication. In the code example above, I only have to declare the constructor once. This is a simple and largely trivial example, but it means that any code I write that inherits from my base class results in exactly the same behaviour in building up the class. I have completely removed the IsValid code from my derived classes, by providing an implementation for my abstract method (note that abstract has been removed from the method name here because I am supplying the real code).

Testing the implementation

I am going to test the implementation of my code. To start with, I am going to use the same method to add the validation items that I did in the last post.

const validation: Validate[] = [];
validation.push(new MinimumLengthValidation('ABC12345', 10));
validation.push(new MinimumLengthValidation('ABC12345AB12345', 10));
validation.push(new MaximumLengthValidation('ABC12345', 10));
validation.push(new MaximumLengthValidation('ABC12345AB12345', 10));

We need to pay attention to the fact that I have created this array as an array of Validate instances. This is going to become important to us because, while I am looping over the validation examples here, I want to call the Debug method, but as this isn’t present in my Validate interface, I can’t do this directly.

validation.forEach((val: Validate) => {
    console.log(val.IsValid());
    // We want to call debug but we can't here.
    // val.Debug(); is not going to work
    // Do something clever here.
});

You see that bit where I say I want to do something clever here? What I want to do here is to do something called a cast. What a cast is, is a way to change one type into another. What I want to do here is to cast the Validate implementation into a LengthValidationBase class so that I can call Debug. To do this, I am going to write the following code, where I use the as keyword to say what I want to cast my class to.

const lengthValidation = val as LengthValidationBase;
lengthValidation.Debug();

In future posts, I am going to deal further with casting, because there are all sorts of cool things we can do with it – far more than we can cover in this one post. For the moment, I will leave you with what my code looks like right now.

validation.forEach((val: Validate) => {
    console.log(val.IsValid());
    // We want to call debug but we can't here.
    // val.Debug(); is not going to work
    const lengthValidation = val as LengthValidationBase;
    lengthValidation.Debug();
});

Conclusion

In this article, we have looked at what inheritance is, and how we can apply it with classes. We discussed making classes abstract and using the protected keyword. We also introduced the ability to cast one type to another. As always, the code for this article is available on Github.

100 days of TypeScript (Day 5)

On day 4 of our journey into TypeScript, we looked at how we could use interfaces to act as data types. As I am about to show you, that’s not all that interfaces can do. In this post, I am going to demonstrate how to use interfaces to set up types so that they must have certain behaviours. For the purposes of this post, I am going to create a simple interface to control validation.

Requirements

The requirements for the validation are going to be really straightforward.

  1. The validation will determine whether a string is greater than or equal to a minimum number of characters.
  2. The validation will determine whether a string is less than or equal to a maximum number of characters.
  3. The validation will use a single method called IsValid to determine whether or not the string is valid.

With these simple requirements in place, I am ready to start writing my code.

Before I start writing the code, I want to address something you might be wondering, namely, why have I written my requirements down? The answer to this is straightforward; as a professional developer, I like to know what it is that I am writing. I find that the act of writing requirements down is a great place for me to start solving the problem I am writing the code for.

The implementation

Okay, getting back to the code. One of my requirements was that I wanted a single method called IsValid that my validation code will use. This is where the interface comes in; interfaces do not have any implementation capabilities so I cannot write any actual logic in my interface, I can say what methods I want to use. This is the code for the interface.

interface Validate {
    IsValid(): boolean;
}

So, now I need to do something with the interface. To fulfil my requirements, I am going to create a class that validates whether or not the string is a minimum length and another class to determine whether or not the class is a maximum length. Both of these classes will use the interface; to do this, I need to use implements to say that the class implements the interface.

class MinimumLengthValidation implements Validate {
    constructor(private text: string, private minimumLength: number) {}
    IsValid(): boolean {
        return this.text.length >= this.minimumLength;
    }
}

You will probably notice that the constructor looks unusual. I have declared text and minimumLength in the signature of the constructor. By marking them as private, I have told TypeScript that I want these assigned here. Effectively this code is exactly the same as this.

class MinimumLengthValidation implements Validate {
    private text: string;
    private minimumLength: number;
    constructor(text: string, minimumLength: number) {
        this.text = text;
        this.minimumLength = minimumLength;
    }
    IsValid(): boolean {
        return this.text.length >= this.minimumLength;
    }
}

The maximum length validation looks remarkably similar to this code unsurprisingly.

class MaximumLengthValidation implements Validate {
    constructor(private text: string, private maximumLength: number) {}
    IsValid(): boolean {
        return this.text.length <= this.maximumLength;
    }
}

Testing the code

Having written the validation classes, I am ready to test them. I could write my code like this.

console.log(new MinimumLengthValidation('ABC12345', 10).IsValid()); // Should print false
console.log(new MinimumLengthValidation('ABC12345AB12345', 10).IsValid()); // Should print true
console.log(new MaximumLengthValidation('ABC12345', 10).IsValid()); // Should print true
console.log(new MaximumLengthValidation('ABC12345AB12345', 10).IsValid()); // Should print false

That doesn’t really demonstrate my validation, so let’s take a look at using the Validate interface. I am going to create an array of Validate items.

const validation: Validate[] = [];

What I am going to do now is push the same validation items from the little snippet above into the array.

validation.push(new MinimumLengthValidation('ABC12345', 10));
validation.push(new MinimumLengthValidation('ABC12345AB12345', 10));
validation.push(new MaximumLengthValidation('ABC12345', 10));
validation.push(new MaximumLengthValidation('ABC12345AB12345', 10));

With this in place, I am going to use a loop to work my way through the array and print out whether or not the validation has succeeded.

for (let index = 0; index < validation.length; index++) {
    console.log(validation[index].IsValid());
}

Coda

We have reached the end of using interfaces to describe what behaviours a class can have. We are starting to move into the territory of inheritance, one of the pillars of Object-Orientation. In the next post, I am going to go further into the world of inheritance and this is where we are really going to pick up the pace.

Thank you so much for reading. As always, the code behind this article is available on github.

100 days of TypeScript (Day 4)

Wow. Day 4 already and we have already covered a lot of material in our quest to go from zero to, well not something cliched, with TypeScript. In the last couple of posts, we delved into using classes in TypeScript so, in this post, I would like to take a bit of a diversion and introduce you to interfaces. Now, if you have come from a language such as C# or Java, you probably think that you won’t learn anything new about interfaces here but interfaces in TypeScript are really cool.

Interfaces as data

One of the things you probably noticed when we were looking at classes is that they can have behaviour. In other words, they aren’t just about data, they also give you the ability to add functionality to manipulate the data. That is incredibly useful but sometimes we want the ability to create something to represent just the data itself. We want to be able to create a type-safe representation of some useful piece of data. You have probably jumped ahead already and thought “I bet Pete’s going to say that interfaces can solve this for me”, and you would be right.

For this post, we are going to create something that represents an email message. We will be able to add recipients, a subject, and the message itself. I am going to start off by writing an interface to represent a single recipient. To create an interface, I change the class keyword for interface so my recipient will look just like this.

interface Recipient {
    email: string;
}

If I wanted to create an instance of a recipient, I could do something like this.

const recipient: Recipient = { email: 'peter@peter.com' };

Variable declarations

As a side note, you will have seen that I have been declaring variables using the const keyword but I have not actually explained where it comes from or what it means. When I started talking about TypeScript, I briefly covered that it was developed to compile to JavaScript. JavaScript has three ways of declaring variables, var, let and const. Originally, JavaScript only had one way, using var, but this was highly problematic. A little while back, let and const were introduced to be a better, less troublesome form of declaration.

Let’s take a look at why var is such an issue. The issue is down to something called block scope. Block scope refers to where a variable can be seen – it should only be visible in the block that it is being declared in so it would probably come as a surprise that the following bit of code lets me see data that it shouldn’t.

for (var i = 0; i < 10; i++) {
  console.log(i);
}
console.log(i); // Wait, why can I see i here?

What we are seeing in this code is var keyword not being covered by the block scope. This can lead to unfortunate side effects in more complicated code because the value becomes unpredictable.

Enter our heroes, let and const.

These were introduced to help us declare variables that respect block scope. We have two keywords because let allows us to declare a variable and then change the value later on, whereas const allows us to declare the variable but it cannot be changed.

Back to our interface

I have created a simple recipient interface and now I am ready to add one that covers the email itself. The email interface will consist of To, CC and BCC recipients lists, as well as the Subject and Message. If we think about things before we start writing code, we make our lives a lot easier so I am going to ensure that the person using the email interface can choose which of the recipients they want to add. As we have a strong type for our recipient, I am going to use a little TypeScript trick and say that the recipients can receive an array of recipients or the recipient can be null using | null.

interface Email {
    To: Recipient[] | null;
    CC: Recipient[] | null;
    BCC: Recipient[] | null;
    Subject: string;
    Message: string;
}

The syntax of Recipient[] | null reads that I want an array of Recipient items OR I want it to be null.

Now that I have my interface, I am going to create a simple function that accepts an Email and write it to the console.

function sendMessage(message: Email) {
    console.log(message);
}
sendMessage(email);

With all the bits and pieces discussed above, you will probably guess that the interface is going to be populated using the const keyword, just like this (this has to go before the sendMessage(email); line).

const email: Email = {
    To: [{
        email: 'bob@bob.com'
    }],
    CC: [{
        email: 'terry@terry.com'
    }, {
        email: 'chris@chris.com'
    }],
    BCC: null,
    Subject: 'This is my email',
    Message: 'This is the message inside my email'
};

Notice that I still had to add the BCC. Without this part, the “shape” of the object would not match the interface and TypeScript is really good at catching things like that.

A quick note about adding individual items to an array. In the recipient entries, each recipient was surrounded by { }. This is how we add an individual entry into the array, so adding multiple ones is simply a matter of separating these { } pairs with a comma.

We have reached the end of our introduction to interfaces. They can do so much more so, in the next post, I am going to show how classes and interfaces work together.

The code for this post can be found on github.

100 days of TypeScript (Day 3)

Welcome back to a series about learning TypeScript from basics through to some pretty advanced stuff. In Day 2, we learned how we can create a simple class using TypeScript. Today we are going to explore classes in more depth, showing how we can add our own constructors and how we can change whether or not code outside our class can see our fields.

Requirements

I have to admit that I’m a bit bored with writing a simple addition class so I am going to write a class that has a little bit more to it. Today, I am going to write a Point class. As a professional developer, I like to have an idea about what I want my class to do so I am going to give it the following requirements.

  1. The class will allow me to add an x and a y value to represent a single point.
  2. The class will provide me with an IsEmpty method so I can determine whether or not the x and y numbers aren’t set to 0,0.
  3. The only way to change the x and y value is through an Offset method.
  4. I will be able to add a Point to a point to get a new point.
  5. I can determine whether two points are equal (have the same coordinates) through an IsEqual method
  6. I will have a ToString method which will tell people using the class what the x and y values are.

The code for today’s exercise is available here. If you look at the code, you will see that I have created a tsconfig.json file. This is exactly the same file I created for Day 2 and Day 1 so you could copy the one you created previously or add a new one using

tsc --init

Getting started

In my day3.ts class, I am going to start by creating the basic class structure.

class Point {
}

A quick sidenote

You might wonder why you haven’t seen anything called object, but I keep talking about object-oriented programming. I have seen many complicated explanations but there is a really simple explanation. When we took about an object, we are talking about something that has been created by the application while it is running; a class is the template for the object so when we create a new instance of our class (instantiate the class is another term you might see), we have actually created an object. We can write a program with thousands of classes; they aren’t useful until we actually create instances from them.

The constructor

When we create an instance of any classes we are writing, you can think of it as we are constructing the class. To help us construct the instance, we have a special method called a constructor. This method is especially interesting because it helps us to get the instance into a start that we can use it, so it can have a large effect on what happens while the class is being instantiated. As this method is used to construct the instance, you can’t call it directly from TypeScript. The only thing that has direct interaction with it is the new keyword. So, what does a constructor look like?

In TypeScript, a constructor uses the constructor keyword like this.

constructor() {
}

Hint: If your constructor looks like this, you can remove it. If you don’t add a constructor to your class, one is automatically “added” for you that looks like this. You won’t see it in your code, but it is there. This is the reason I didn’t add a constructor to my code or Day 2.

In my requirements, I said that the class would allow me to add x and y values to represent the point. To do this, I am going to pass these values into the constructor like this.

constructor(x: number, y: number) {
}

With this in place, anywhere that I needed to create an instance of this class, I can create it like this.

class Point {
    constructor(x: number, y: number) {
    }
}
const point: Point = new Point(0, 0);

Note: As I have added a constructor with parameters, I no longer have access to the default constructor, so I am forced to use the constructor with parameters here.

I have passed values in, but I am not actually doing anything with them. The will not be available to any method that needs them because they are visible only to the constructory. I am going to fix this by adding a couple of fields to store these values. One of my requirements is that the only way to change the value of the fields is to use an Offset method so this suggests that I should not be able to access them directly from outside the class. To do this, I am going to introduce the private keyword. What private does is tell the compiler that this field will only be visible inside the class.

You are probably thinking that we cannot make everything private and that would be correct. By default, TypeScript makes things inside the class public but you can also explicitly set things to public.

Our private fields are going to look like this.

private x: number;
private y: number;

If you remember, in Day 2, I had to assign a default value to our fields when I created them. When I assign values to them in the constructor, the compiler is clever enough to know that I don’t have to assign default values. My constructor now looks like this.

constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
}

Upcoming. In a future post, I will show you a handy trick of TypeScripts where I can declare a field in the signature of the constructor.

I am now going to address my other requirements. Let us start with the ability to check whether or not a point is empty. I have taken the decision here that an empty point is one where the x and y values are both set to 0.

public IsEmpty(): boolean {
    return this.x === 0 && this.y === 0;
}

The next method I am going to write checks whether two points are equal. Equality, in this case, is whether the x values in both points are the same and the y values are the same. As this code will run in an instance of the class, I only need to pass in the Point that I want to compare against.

public IsEqual(point: Point): boolean {
    return this.x === point.x && this.y === point.y;
}

With little increments of code like this, I can quickly add all the functionality that I need. The ability to offset my coordinates looks like this.

public Offset(x: number, y: number) {
    this.x = this.x + x;
    this.y = this.y + y;
}

Important note: There is a shorthand way to add another value to an existing one. If I use += in my code, I can change

this.x = this.x + x;

to

this.x += x;

Rather than going through the other methods, I will add the whole class here so you can see what the ToString and Add methods look like. By now, you should have a good idea about what these methods would probably do.

class Point {
    private x: number;
    private y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    public IsEmpty(): boolean {
        return this.x === 0 && this.y === 0;
    }

    public IsEqual(point: Point): boolean {
        return this.x === point.x && this.y === point.y;
    }

    public Add(point: Point): Point {
        return new Point(point.x + this.x, point.y + this.y);
    }

    public ToString(): string {
        return 'X is ' + this.x + ' Y is ' + this.y;
    }

    public Offset(x: number, y: number): void {
        this.x += x;
        this.y += y;
    }
}

If I want to demonstrate this code in operation, I can write something like this.

const point: Point = new Point(0, 0);
console.log('Point is empty is ' + point.IsEmpty()); // Should be true
point.Offset(10, 20);
console.log('Point is empty is ' + point.IsEmpty()); // Should be false
const offsetPoint = new Point(10, 20);
console.log('Points are equal is ' + point.IsEqual(offsetPoint)); // Should be true
console.log('The offset is ' + point.Add(offsetPoint).ToString()); // X is 20 and Y is 40

We have reached the end of the code for Day 3. I appreciate that there is a lot to take in here, from creating a custom constructor, adding scope modifiers (public/private) and a little bit of alternate addition syntax. Please browse the code from github and, if you have any questions, don’t be afraid to ask. In day 4, I am going to introduce you to interfaces in TypeScript. If you have used interfaces in a language like C# or Java, the way that TypeScript lets you use them looks nothing short of miraculous.

100 days of TypeScript (Day 2)

In 100 days of TypeScript (Day 1), I created a basic TypeScript “application” where two numbers could be added together. This was intended to introduce you to get the pre-requisites in place for writing TypeScript code, as well as acquaint you with using the type system. I promised, at the end of the post, that I would rewrite this application to use the TypeScript class system instead.

Before I start writing the code, it is worth looking at what classes are, both in a general sense and then in how they relate to TypeScript/JavaScript.

Simply put, a class is something that allows us to group data and behaviour together into an object; this sounds complicated, but is actually really simple. The idea about using a class is that we put everything that we need to do in one place. Imagine that I want to group together everything to do with playing a guitar, so I create a guitar class. This has certain attributes (data) that applies to it such as the number of strings, the type of guitar it is, the manufacturer, model; possibly it has pickups, and so on. These could all be grouped together into one class called Guitar. It also has things that we can do to it, so for an electric guitar, we can choose which pickups we are using, we can adjust the tone controls or change the way the guitar is tuned. These behaviours or actions can all be added to the Guitar class. In other words, everything we need is grouped into one object.

Note: In a future post, I’ll demonstrate how we would break that Guitar class down into smaller classes that are much more specialist.

When TypeScript was first created, classes were something that were being considered for JavaScript, but which hadn’t actually been officially released. TypeScript allowed us to write code that used classes, and outputted code that JavaScript would use without having the class keyword; when classes were formally added to JavaScript, our TypeScript code could be recompiled to use them natively.

So, what does a class look like? For out addition class, we can start out with an empty definition that looks like this.

class Addition { }

This isn’t very useful as it stands, so I am going to add something called fields to represent the two numbers I want to add together. A field is just the name we give to the thing that holds the data for our class. Adding our fields looks like this.

class Addition { 
    number1: number = 0;
    number2: number = 0;
}

In the code here, I have added my two number fields and given them an initial value of 0. I had to give them an initial value because TypeScript complains there is no value if I don’t.

Before I get into the part where I create our add method, let’s take a look at how I put values into number1 and number2. In order to get to these two fields, I have to do something called instantiation. So, Addition is our class – to use it, we create an instance of the class (this is why it’s called instantiation). To create an instance of our class, we use a special keyword called new. It looks just like this.

const additionInstance = new Addition();

With this, I now have the ability to set the values of number1 and number2 directly.

additionInstance.number1 = 10;
additionInstance.number2 = 20;

Going back to the Addition class, I am now going to write the addition method (In object-orientation, you can think of a method as the name we give to a function).

public Add(): number {
    return this.number1 + this.number2;
}

In my Add method, I get access to the number1 and number2 fields with the special this keyword. What this does is give methods in the class access to other parts of the current instance of the class.

Now that I have completed the Add method, I can now call it from my instantiated code. The instantiation code now looks like this.

const additionInstance = new Addition();
additionInstance.number1 = 10;
additionInstance.number2 = 20;
console.log(additionInstance.Add());

And that’s it. We have created our first TypeScript class here. In the next tutorial, I will demonstrate how we can hide fields so they cannot be accessed outside the instance of the class and introduce constructors that help us to instantiate our classes with a bit more flair.

The code for this post can be found here.

100 Days of TypeScript (Day 1)

Introducing TypeScript

It’s been a while since I’ve had the chance to write in this blog and I really wanted to come up with something different for me. If you’re a long time follower of mine, you probably know that I wrote a book on TypeScript a couple of years ago, so I thought it would be fun for me to embark on one of those 100 Days of types of blog and write a series introducing you to TypeScript if you’ve not used it before; give you a brush up on things you already know if you’ve used it, and maybe introduce you to some new things that you might not have come across before.

Note: This blog series isn’t going to be a continuous 100 days of posting, it’s 100 days by the end.

So, what is TypeScript? If you go to the TypeScript website, the tagline is “TypeScript is JavaScript with syntax for types”. What does that actually mean?

TypeScript was originally built out of the idea that writing high quality JavaScript was difficult. While that’s a subjective opinion, TypeScript rapidly evolved, giving us the ability to use up and coming JavaScript features via polyfills (don’t worry about this, we’ll come back to this in a future post). TypeScript now ranks as one of the most popular languages around.

Getting Started

Okay, you can develop TypeScript apps online in the playground, but I really recommend installing it locally. To do that, you’re going to need to use something like npm, yarn or pnmpm. If you don’t have npm installed, you need to install Node to get it. Assuming you have installed Node, you can install TypeScript with the following command (depends on the package manager you’re using).

npm install -g typescript

It’s time to write our first TypeScript application (all code is available in github).

This is going to be a simple program to add two numbers together. I’m going to use the TypeScript compiler to set some things up ready for when I want to compile my TypeScript code.

tsc --init

This has created a file called tsconfig.json which sets up compiler options that determine what our JavaScript will look like when we’ve compiled it from TypeScript; oh wait, didn’t I mention that TypeScript compiles down to JavaScript? A quick note – I pretty much always use Visual Studio Code for editing my TypeScript; it’s a great choice if you’ve not used it before.

I’m going to add a file called day1.ts to add my TypeScript to add my first piece example. The .ts extension tells us that this is a TypeScript file. If you have used JavaScript before, the code will look familiar to you. This is what our add function would look like as a JavaScript method.

function add(number1, number2) {
    return number1 + number2;
}

I said that I wanted the add function to be able to add two numbers. I don’t want it to add two strings together or a date and a string. This is where the first strength of TypeScript really comes into its own, and where the TypeScript tagline makes sense. I am going to constrain the function to accept numbers and return a number using the following syntax.

function add(number1: number, number2: number): number {
    return number1 + number2;
}

If I attempt to pass something that’s not a number to either of the parameters, I won’t be able to compile the code. I can’t pass “special” values such as undefined or null to either of the parameters. In other words, I have just written something that will protect me from myself.

In order to test my code, I’m going to call the function and pass the output to the console window like this.

console.log(add(10, 20));

After saving the file, I want to “compile” the TypeScript code so that it turns into JavaScript. To do this, I simply run the tsc command with no parameters. This picks up the contents of the tsconfig.json file and uses that to control how the file is compiled. (The tsc command here should be run in the same directory as the tsconfig.json file).

Now that I have compiled my code, I can run it using the following command.

node day1.js

And that’s it; that’s the first TypeScript program. In day 2, we are going to look at how to change our function over so that it sits inside a class; which will let us see how we can start to leverage object oriented concepts to build reusable blocks.

FluentRealSense – the first steps to a simpler RealSense

Those who know me are aware that I have a long term association (nay, let’s say it for what it is, love affair) with the RealSense platforms from Intel. If you’ve been following developments in that space for any length of time, you’re probably aware that things have moved on a lot and the cameras are available in all sorts of devices and are no longer just limited to the Windows platform. This shift of emphasis means that Intel have moved away from concentrating on the old monolithic RealSense SDK and have moved to supporting a new open source API (available here: https://github.com/IntelRealSense/librealsense).

I have spent a period of time working with this API as it has evolved and have started “wrapping” it to make it a little bit friendlier to use (in my opinion) for people who don’t want to get bogged down with the “nitty gritty” of how to get devices, and so on. This work has been in C++, the language the API is available in, and I am going to cover, over a series of posts, how this library evolved. I’ll show you the code I’ve written at each step so that you can also see how I have gone about relearning modern C++ (bearing in mind it has been 18 years since I last worked with it in anger) so you will definitely find that early iterations of the code are naive, at best. My aim with this library was to make it as fluent as possible, hence it’s name, FluentRealSense.

An upfront note. Early iterations of this codebase have been done entirely on Windows running Visual Studio 2017. I chose this particular environment because, a) Visual Studio is, to my mind, the finest IDE around and b) because 2017 supports porting your C++ code directly over to Linux. This lets me leverage the rapid turnaround time I’m used to in my dev environment and the ease of deploying to my intended targets later on. Thank you Microsoft for keeping this old developer happy.

Let’s start with the first iteration. The first thing I wanted the code to do was to provide me with the ability to iterate over all the cameras on my system and print out some diagnostic information. This meant that my code would be broken down initially into three classes:
information: This class reads information from the API about a single camera and returns it as a string.
camera: This is a single device. Initially, it’s just going to instantiate and provide access to the information class.
cameras: The entry point for consuming applications, this class is responsible for finding out about and managing access to each camera; this class is also enumerable so that the calling code can quickly iterate over each camera.

Let’s start off by looking at the information class. First we’re going to add some includes and namespaces:

#pragma once
#include "hpp/rs_context.hpp"

using namespace std;
using namespace rs2;

class information
{
public:
class information() {}
~information() {}
}

That’s all very straightforward and nothing you won’t have seen before. Let’s start fleshing this out.

The first thing we’re going to need is a RealSense device to get information from – this is going to be passed in so let’s add a member to store it and replace our constructor with this:

explicit information(const device device) : device_(device) {}
:::
private:
device device_;

At this stage, our code looks like this:

#pragma once
#include "hpp/rs_context.hpp"

using namespace std;
using namespace rs2;

class information
{
public:
explicit information(const device device) : device_(device) {}
~information() {}

private:
device device_;
}

I have to say, at this point, I love the improvements to instantiating members that C++ now provides. This is a wonderful little innovation.

Now, in order to get the information out of the API, I’m going to add a handy little private helper method. This makes use of the fact that the API exposes this information via an rs2_camera_info enumeration:

const char* get_info(const rs2_camera_info info) const
{
if (!device_.supports(info))
{
return "Not supported";
}
return device_.get_info(info);
}

This is the first point that our code is going to add any value. Whenever we call get_info against the underlying device, we have to check that that particular type of info can be retrieved for that device. It’s very easy to write code that makes assumptions that each camera supports exactly the same set of properties here so the underlying call could throw an exception. To get around this, our code checks to see if the device supports that particular rs2_camera_info type and returns “Not supported” if it doesn’t. It is so easy to forget that you should always pair the get_info with the supports, so this helper method removes the need to remember that.

So, how do we use this? Well, with some public methods like these:

const char* name() const
{
return get_info(RS2_CAMERA_INFO_NAME);
}

const char* serial_number() const
{
return get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
}

const char* port() const
{
return get_info(RS2_CAMERA_INFO_PHYSICAL_PORT);
}

const char* firmware_version() const
{
return get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
}

const char* debug_opCode() const
{
return get_info(RS2_CAMERA_INFO_DEBUG_OP_CODE);
}

const char* advanced_mode() const
{
return get_info(RS2_CAMERA_INFO_ADVANCED_MODE);
}

const char* product_id() const
{
return get_info(RS2_CAMERA_INFO_PRODUCT_ID);
}

const char* camera_locked() const
{
return get_info(RS2_CAMERA_INFO_CAMERA_LOCKED);
}

string dump_diagnostic() const
{
string text = "\nDevice Name: ";
text += name();
text += "\n Serial number: ";
text += serial_number();
text += "\n Port: ";
text += port();
text += "\n Firmware version: ";
text += firmware_version();
text += "\n Debug op code: ";
text += debug_opCode();
text += "\n Advanced Mode: ";
text += advanced_mode();
text += "\n Product id: ";
text += product_id();
text += "\n Camera locked: ";
text += camera_locked();

return text;
}

We now have our complete information class. It looks like this:

#pragma once
#include "hpp/rs_context.hpp"

using namespace std;
using namespace rs2;

class information
{
public:
explicit information(const device device) : device_(device) {}
~information()
{
}

const char* name() const
{
  return get_info(RS2_CAMERA_INFO_NAME);
}

const char* serial_number() const
{
  return get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
}

const char* port() const
{
  return get_info(RS2_CAMERA_INFO_PHYSICAL_PORT);
}

const char* firmware_version() const
{
  return get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
}

const char* debug_opCode() const
{
  return get_info(RS2_CAMERA_INFO_DEBUG_OP_CODE);
}

const char* advanced_mode() const
{
  return get_info(RS2_CAMERA_INFO_ADVANCED_MODE);
}

const char* product_id() const
{
  return get_info(RS2_CAMERA_INFO_PRODUCT_ID);
}

const char* camera_locked() const
{
  return get_info(RS2_CAMERA_INFO_CAMERA_LOCKED);
}

string dump_diagnostic() const
{
  string text = "\nDevice Name: ";
  text += name();
  text += "\n Serial number: ";
  text += serial_number();
  text += "\n Port: ";
  text += port();
  text += "\n Firmware version: ";
  text += firmware_version();
  text += "\n Debug op code: ";
  text += debug_opCode();
  text += "\n Advanced Mode: ";
  text += advanced_mode();
  text += "\n Product id: ";
  text += product_id();
  text += "\n Camera locked: ";
  text += camera_locked();
  return text;
}

private:
  const char* get_info(const rs2_camera_info info) const
  {
    if (!device_.supports(info))
    {
      return "Not supported";
    }
    return device_.get_info(info);
  }
  device device_;
};

The next thing we have to do is write a class that represents a single RealSense camera. There’s not much to this class, at the moment, so let’s look at it in its entirety.

#pragma once
#include "hpp/rs_context.hpp"
#include "information.h"

using namespace std;
using namespace rs2;

class camera
{
public:
  explicit camera(const device dev) : information_(make_shared(dev)) {}

  ~camera()
  {
  }

  shared_ptr get_information() const
  {
    return information_;
  }

private:
  shared_ptr information_;
};

I did say this class was pretty light at the moment. The class accepts a single RealSense device which is used to instantiate the information class. We provide one method which is used to get the instance of the information class. That’s it so far.

Finally, we come to the entry point of our code, the cameras class. This class let’s us enumerate all of the cameras on our system and access the functions inside. As usual, we’ll start off with the definition:

#pragma once
#include 
#include 
#include "camera.h"
#include "hpp/rs_context.hpp"

using namespace std;
using namespace rs2;

class cameras
{
public:
  cameras() {}
  ~cameras() {}
}

As you will remember, I said that I wanted the cameras to be enumerable so I need to do some upfront declarations:

using cameras_t = vector<shared_ptr>;
using iterator = cameras_t::iterator;

using const_iterator = cameras_t::const_iterator;
[/source]

With these in place, I can now start to add the ability to enumerate over the camera instances. Before I do that, though, it’s time to introduce something new. In the preceding code, we saw that the RealSense camera was represented as a device that we passed into the relevant constructors. The question is, how did we get that device in the first place? Well, that’s down to the API providing a context that allows us to access these devices. So, let’s add a member to store a vector of camera instances and then build in the method to get the list of devices.

cameras() : cameras_(make_shared())
{
  context context;
  // Iterate over the devices;
  auto devices = context.query_devices();
  for (const auto dev : devices)
  {
    const auto cam = make_shared(dev);
    cameras_->push_back(cam);
  }
}

private:
  shared_ptr cameras_;

There’s nothing complicated in that code. We get the devices from the context using query_devices and iterate over each one, adding a new camera instance to our vector. We have reached the point where we can now add the ability to enumerate over our vector. All the scaffolding is in place so let’s add that capability.

int capacity() const
{
  return cameras_->capacity();
}

iterator begin() { return cameras_->begin(); }
iterator end() { return cameras_->end(); }

const_iterator begin() const { return cameras_->begin(); }
const_iterator end() const { return cameras_->end(); }
const_iterator cbegin() const { return cameras_->cbegin(); }
const_iterator cend() const { return cameras_->cend(); }

That’s it. We now have the ability to build and iterate over the devices on our system. Let’s see how we would go about using that. To test it, I created a little console application that I used to call my code. It’s as easy as this:

#include "stdafx.h"
#include "cameras.h"
#include 

int main()
{
const auto devices = std::make_shared();
for (auto &dev : *devices)
{
cout <get_information()->dump_diagnostic();
}
return 0;
}

This is what it looks like on my system (running a web camera and a separate RealSense camera).

real-sense-images

Solving the RealSense platform conundrum

When I develop RealSense applications I invariably use Visual Studio and C# to write my applications. If you’ve done any RealSense development in .NET, you’re aware that they have a 32 bit and 64 bit version of their assemblies and you’ve probably had to deal with the conundrum about making your application support 64 bit or 32 bit assembly references. In most of the examples I have seen, the developers plump for adding references to only one platform – which is a real shame. With just a little bit of Visual Studio trickery, you can use target both platforms – in this post, I’m going to introduce you to a little command line tool that I wrote that sets your apps up to support x86 and x64.

Basically, what we’re going to do here is copy the relevant libs files from the Realsense SDK and copy them into a Libs folder in the solution folder. Obviously, we need to reference these files so the code will create x86 and x64 references inside our csproj files (and create the matching entries in the solution as well). As only one of the files is a .NET file, we need to copy the unmanaged DLL it relies on into the output folder as well. This last part is done by creating a post build event to copy the file over on successful completion of the build.

Using it is pretty straightforward – you’ll need to change the root folder for your RealSense installation inside the .config file. Look for the RSSDK key and enter your root directory – in my case, it’s C:\Intel\RSSDK, so when the code is running it uses this to build up the C:\Intel\RSSDK\bin\win32 and C:\Intel\RSSDK\bin\x64 folders. So, you need to make sure you change this value to point to the directory immediately above the bin folder.

When you run the application (it’s a console application so you’re best off running it in a command window), pass in the name of the directory that you want to update to RealSense – the code looks for all solution files and csproj files from the directory you pass in – don’t worry about the nesting level of these files, the code effectively walks the tree looking for these files. So, when I wanted to add RealSense to all of the solution and project files under C:\Dev\TestRealsenseMaker, I ran the command MakeRealsense C:\Dev\TestRealsenseMaker. And that’s it. That’s all I needed to do to make my files RealSense ready. Happy coding.

MakeRealsense.zip

Note: WordPress doesn’t like zip files, so you’ll need to rename the file from MakeRealsense.zip.doc to MakeRealsense.zip when you have downloaded it.

Sensing the future with WPF

This post is a look into a new library that I’m writing that’s intended to make life easier for WPF developers working with Intel RealSense devices. As many of you may know, I’ve been involved with the RealSense platform for a couple of years now (back from when it was called the Perceptual Computing SDK). When I develop samples with it, I tend to use WPF as my default development experience, and the idea of hooking up the Natural User Interface capabilities of RealSense devices with the NUI power of WPF in an easy to use package is just too good to resist. On top of this, I still strongly believe in WPF and it will take a lot to remove me from developing desktop applications with it because it is just so powerful.

To this end, I have started developing a library called RealSenseLight that will enable WPF developers to easily leverage the power of RealSense without having to worry about the implementation details. While it”s primarily aimed at WPF developers, the functionality available will be usable from other C# (Windows Desktop) applications, so hooking into Console applications will certainly be possible.

One of the many decisions I’ve taken is to allow configuration of features to be set via Fluent interface, so it’s possible to do things like this:

RealSenseApplication.Uses(new EmotionDetectionConfiguration())
  .Uses(SpeechRecognition.DefaultConfiguration().ChangePitch(0.8))
  .Start();

ViewModels will be able to hook into RealSense using convenient interfaces that abstract the underlying implementations. There’s no need to call Enable… to enable a RealSense capability. The simple fact of integrating a concrete implementation means that the feature is automatically available. The following example demonstrates what an IoC resolved implementation looks like:

public class EmotionViewModel : ViewModelBase
{
  private IEmotion _emotion;
  public EmotionViewModel(IEmotion emotion)
  {
    emotion.OnUserHappy(user =&gt; System.Debug.WriteLine(&quot;{0} is happy&quot;, user.DetectedUser));
  }
}

The library will provide the ability to do things such as pause/resume individual RealSense capabilities, identify and choose from the relevant RealSense compatible devices, although this does require identifying up front, what the different aspects are you’re interested in because it uses these to evaluate the devices that meet these capabilities.

I’m still fleshing out what the whole interface will look like, so all of the features haven’t been determined yet, but I will keep posting my designs and a link to the repo once I have it in a state where it’s ready for an initial commit.

Getting a RealSense of my status

Long time readers will have realised that I have been spending a lot of time with the technology that was formally known as Perceptual Computing (PerC). You may also know that this technology is now known as RealSense and that it will be rolling out to a device near you soon. What you might not know is that I’m currently writing a course on this technology for Pluralsight. As part of writing this course, I’ve been creating a few little wrapper utilities that will make your life easier when developing apps with the SDK.

In this post, I’m going to show you a handy little method for working with API methods. Pretty much every RealSense API method returns a status code to indicate whether or not it was successful. Now, it can get pretty tedious writing code that looks like this:

pxcmStatus status = Session.CreateImpl<PXCMVoiceRecognition>
  (PXCMVoiceRecognition.CUID, out voiceRecognition);
if (status < pxcmStatus.pxcmStatus.PXCM_STATUS_NO_ERROR)
{
  throw new InvalidStatusException("Could not create session");
}
status = _voiceRecognition.QueryProfile(out pInfo);
if (status < pxcmStatus.pxcmStatus.PXCM_STATUS_NO_ERROR)
{
  throw new InvalidStatusException("Could not query profile");
}

As you can imagine, the more calls you make, the more status checks you have to do. Well, I like to log information about what I’m attempting to do and what I have successfully managed to do, so this simple method really helps to write information about the methods being invoked, and to throw an exception if things go wrong.

public void PipelineInvoke(Func<pxcmStatus> pipelineMethod, string loggingInfo = "")
{
  if (!string.IsNullOrWhiteSpace(loggingInfo))
  {
    Debug.WriteLine("Start " + loggingInfo);
  }
  pxcmStatus status = pipelineMethod();
  if (status < pxcmStatus.PXCM_STATUS_NO_ERROR)
  {
    throw new InvalidStatusException(loggingInfo, status);
  }
  if (!string.IsNullOrWhiteSpace(loggingInfo))
  {
    Debug.WriteLine("Finished " + loggingInfo);
  }
}

This makes it easier to work with the API and gives us code that looks like this:

PipelineInvoke(() => 
  Session.CreateImpl<PXCMVoiceRecognition>(PXCMVoiceRecognition.CUID, 
  out _voiceRecognition), "creating voice recognition module");

And this is what InvalidStatusException looks like:

public class InvalidStatusException : Exception
{
  public InvalidStatusException(string alertMessage, pxcmStatus status)
  {
    Message = alertMessage;
    Status = status;
  }
  public string Message { get; private set; }
  public pxcmStatus Status { get; private set; }
}

Over the course of the next couple of months, I’ll share more posts with you showing the little tricks and techniques that I use to make working with the RealSense SDK a real joy.