Channels ▼
RSS

Database

Microsoft TypeScript: The Lay of the Land


When you initialize variables or call functions to assign values to variables, you won't need to add explicit types because the type inference mechanism will generate the type information for both the TypeScript language service in the code editor and the compiler. Thus, you can detect errors related to types without having to use explicitly typed variables everywhere. For example, consider the following explicitly typed variable declaration:

  var url: string = "www.drdobbs.com";

It isn't necessary to use the explicitly string typed variable declaration in order to enable type checking for TypeScript. TypeScript will know that the url variable is a string with just the following line:

  var url = "www.drdobbs.com";

TypeScript allows you to easily specify optional parameters with default values. The following simple TypeScript code adds an optional fractionDigits parameter to the calculateCircleArea function by adding a question mark (?) to the parameter name. Notice that the default value for fractionDigits is 2. Thus, there is no need to explicitly specify the number type because TypeScript will infer it (Figure 6):

//// TypeScript code
function calculateCircleArea(radius: number, fractionDigits? = 2) {
	return (Math.PI * Math.pow(radius, 2)).toFixed(fractionDigits);
}

The TypeScript editor displaying a tooltip with the parameters and types
Figure 6: The TypeScript editor displaying a tooltip with the parameters and types for the calculateCircleArea function.

The following lines show the JavaScript code that the TypeScript compiler generates:

 
//// JavaScript code generated by the TypeScript compiler
function calculateCircleArea(radius, fractionDigits) {
    if (typeof fractionDigits === "undefined") { fractionDigits = 2; }
    return (Math.PI * Math.pow(radius, 2)).toFixed(fractionDigits);
}
alert(calculateCircleArea(10).toString());

In this case, the TypeScript compiler added the necessary JavaScript lines to check whether the type of fractionDigits is undefined. If the type is undefined, the code sets the default value of 2 to fractionDigits. This way, the call to the calculateCircleArea function with just the radius parameter specified works without problems and is a valid call. The syntax in TypeScript to define an optional parameter is easier to read than the JavaScript lines. In addition, TypeScript supports the object types, which will be further explored in a future article.

Interfaces

TypeScript supports interfaces as compile-time constructs that don't have a runtime representation; that is, they don't generate JavaScript code. You can use interfaces to declare a new named object-type and validate that required objects are passed as parameters and returned from functions.

Suppose you're developing a game that has aliens as the main characters. The following simple TypeScript code defines an Alien interface with the desired types for name, angle, bonus and rotationSpeed. The introduceAlien function receives an Alien and uses both its name and bonus to display a message:

//// TypeScript code
interface Alien {
	name: string;
	angle: number;
	bonus: number;
	rotationSpeed: number;
}

function introduceAlien(alien: Alien) {
	return "I am " + alien.name + " and my bonus is " + alien.bonus.toString() + ".";
}

alert(introduceAlien({ name: "DrDobbsAlien", angle: 0, bonus: 5000, rotationSpeed: 5 }));

The following lines show the JavaScript code that the TypeScript compiler generates from this simple code. Notice that the interface doesn't generate JavaScript, so you just have the lines that define the introduceAlien function and the code that calls it:

//// JavaScript code generated by the TypeScript compiler
function introduceAlien(alien) {
    return "I am " + alien.name + " and my bonus is " + alien.bonus.toString() + ".";
}
alert(introduceAlien({
    name: "DrDobbsAlien",
    angle: 0,
    bonus: 5000,
    rotationSpeed: 5
}));

Now, if you were to enter alert(introduceAlien({ and then press Ctrl + Space, the TypeScript editor would display a context menu with the four fields of the Alien interface (see Figure 7) because the editor knows that introduceAlien requires an Alien as defined in the interface. Thus, the interface enables you to reduce the number of runtime errors when functions require or return objects with certain fields.

The TypeScript editor displaying a context menu with the four fields from an interface.
Figure 7: The TypeScript editor displaying a context menu with the four fields of the Alien interface.

TypeScript supports classes and inheritance, which allows you to create derived classes that specialize base classes. When you define classes, the TypeScript compiler generates JavaScript code for them, but the member's accessibility disappears in JavaScript, as you will see in this example. TypeScript enforces private accessibility at compile-time, but there is no code that defines members as private at runtime. The following TypeScript code defines a BadAlien class that implements the previously introduced Alien interface. The code uses the previously shown introduceAlien function, which requires an Alien and, in this case, receives a BadAlien instance:

//// TypeScript code
class BadAlien implements Alien {
	damagePower: number;
	
	constructor(public name: string, public angle: number, public bonus: number, public rotationSpeed: number) {
		this.damagePower = 0.1 * bonus;
	}
}

interface Alien {
	name: string;
	angle: number;
	bonus: number;
	rotationSpeed: number;
}

function introduceAlien(alien: Alien) {
	return "I am " + alien.name + " and my bonus is " + alien.bonus.toString() + ".";
}

var firstBadAlien = new BadAlien("DrDobbsBadAlien", 0, 5000, 5);

alert(introduceAlien(firstBadAlien));

The following lines show the JavaScript code that the TypeScript compiler generates. Notice how the BadAlien class and its constructor are translated to functions:

//// JavaScript code generated by the TypeScript compiler
var BadAlien = (function () {
    function BadAlien(name, angle, bonus, rotationSpeed) {
        this.name = name;
        this.angle = angle;
        this.bonus = bonus;
        this.rotationSpeed = rotationSpeed;
        this.damagePower = 0.1 * bonus;
    }
    return BadAlien;
})();
function introduceAlien(alien) {
    return "I am " + alien.name + " and my bonus is " + alien.bonus.toString() + ".";
}
var firstBadAlien = new BadAlien("DrDobbsBadAlien", 0, 5000, 5);
alert(introduceAlien(firstBadAlien));

Conclusion

In this article, I've explained the main benefits and features of TypeScript, and provided a brief overview of types, interfaces, and classes, focusing on the TypeScript Playground and the IntelliSense features that also work with Visual Studio 2012. In the next article in this series, I'll explain how you can work with TypeScript in Visual Studio 2012 with the latest versions of the plug-in and the compiler. In addition, I'll dive deeper into the support for classes, inheritance, properties, member accessibility, type assertions, arrow function expressions, modules, and automatically generated declarations that allow you to use all of TypeScript's handy features when consuming the most common JavaScript libraries.


Gaston Hillar is an expert in Windows-based development and is a frequent contributor to Dr. Dobb's.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video