Channels ▼
RSS

.NET

Microsoft TypeScript: The Lay of the Land


TypeScript is an open source superset of JavaScript under development by Microsoft. TypeScript adds support for optional static types, interfaces, classes, and modules to the JavaScript syntax, and translates this input into plain JavaScript. Thus, the resulting code runs in any browser or host. In this article, I introduce some of the most important TypeScript features and show how related tools use them to simplify program construction and maintenance, especially for complex applications. (An upcoming article will explore more subtle benefits of the language.)

JavaScript + Types

Most modern IDEs, including Visual Studio, have dramatically improved support for JavaScript. For example, Visual Studio 2012 provides good code-completion and navigation features for editing JavaScript code. When you work with an ASP.NET MVC 4 project, by default, the Scripts/_references.js file includes references to the files to which Visual Studio will provide JavaScript IntelliSense support. This way, when you edit a JavaScript file, Visual Studio provides autocomplete for the most common libraries, just like jQuery.

However, when it is time to refactor, if you right-click on any variable, the context menu won't display the well-known Refactor | Rename… options (however, there are many third-party add-ins for Visual Studio 2012 that simplify this operation with JavaScript code). In addition, the autocompletion provides a "description of  member variable" as the description for an element, which is not terribly helpful.

The lack of type information can produce runtime errors when you use unexpected types. Appropriate testing will detect the errors, but adding some type information would allow you to detect many errors when writing the code, and the editor would be able to provide you with accurate information about the error. That's the idea behind TypeScript.

If you have worked on an ASP.NET MVC application with a C# back end, you know that when you leave a C# file and start working on the JavaScript pieces, Visual Studio loses a lot of features. For example, you don't have the dropdowns at the top of the editor that allow you to select a desired class and method to make it easier to navigate through the code. One of TypeScript's goals is to make the scripting experience in TypeScript similar in richness to the C# and C++ coding experience, without requiring a completely new scripting language.

As the number of JavaScript files and lines in an application grows, it becomes even more difficult to keep an easy-to-maintain structure. Thus, TypeScript adds support for classes with inheritance, modules, and interfaces to help in solving this problem. The syntax to define classes and modules is aligned with the ECMAScript 6 proposals.

Understanding TypeScript with the PlayGround

The easiest way to understand how TypeScript works is to dabble with the browser-based Playground, which uses the TypeScript language service in the code editor. The same TypeScript language service is available for Visual Studio 2012 with a plug-in. You can visit the TypeScript Playground and start exploring TypeScript code without having to install any additional software. The Playground shows a split-screen editor with the TypeScript code on the left side and the generated JavaScript code on the right (Figure 1).

TypeScript Playground
Figure 1: The TypeScript Playground displaying TypeScript code on the left and the generated JavaScript on the right.

The following simple TypeScript code adds type information for the radius parameter (number type) of the calculateCircleArea function. The type inference mechanism will determine that the function returns a number, and therefore, it isn't necessary to specify the return type:

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

alert(calculateCircleArea(10).toString());

As shown in Figure 1, the generated code is almost the identical: The JavaScript code just removes the type information added for the radius parameter, as shown in the following JavaScript lines:

//// JavaScript code generated by the TypeScript compiler
function calculateCircleArea(radius) {
    return Math.PI * Math.pow(radius, 2);
}
alert(calculateCircleArea(10).toString());

As you might guess, when TypeScript is translated to JavaScript, the type information is completely removed. The static types disappear at runtime, therefore, there is zero cost for adding the types in TypeScript. However, because you provided type information for the radius parameter, the TypeScript editor is able to highlight errors if you supply the wrong parameter types for the calculateCircleArea function. For example, you can change the line that calls the calculateCircleArea function with the following line in the TypeScript editor:

  alert(calculateCircleArea("10"));

The TypeScript editor knows that the radius parameters must be of a number type, but you supplied a string value. Therefore, the function name appears underlined in red. When you hover the mouse over the function name, the editor displays a tooltip with more details about the problem (see Figure 2): "Supplied parameters do not match any signature of call target (radius: number) => number."

The TypeScript editor providing details about the error detected at design-time.
Figure 2: The TypeScript editor providing details about the error detected at design time.

In this case, the code will execute without problems if you remove the type information. However, most of the time, you don't want to lose control of the conversions that happen under the hood, and you really want to receive a numeric value for your calculateCircleArea function. TypeScript provides static analysis based on both the type annotations you add and the structure of the code.

The same will happen if you change the line that calls the calculateCircleArea function with the following line in the TypeScript editor. In this case, the number of supplied parameters is wrong:

  alert(calculateCircleArea(10, 20));

The TypeScript editor also provides autocompletion features. For example, if you enter alert(calculate and then press Ctrl + Space, the editor displays a dropdown menu with the calculateCircleArea function, its required parameter, and the returned type (see Figure 3).

The TypeScript editor provides an autocomplete dropdown menu.
Figure 3: The TypeScript editor provides an autocomplete dropdown menu.

The editor will also highlight an error if you change the line that calls the calculateCircleArea function with the following line in the TypeScript editor (see Figure 4). In this case, the name calculateCircleAreaWithRadius doesn't exist in the current scope, and the code won't produce the expected results at runtime:

  alert(calculateCircleAreaWithRadius(10);

The TypeScript editor provides error details.
Figure 4: The TypeScript editor provides details about the error.

If you click on the radius parameter and then move the mouse pointer, you will see a blue triangle appearing below radius and usage information about this symbol highlighted in the editor. If you click on the blue triangle, the editor displays a context menu with several options (Figure5). Select "Rename symbol (F2)" and enter rad to change the name for radius. This way, you can easily rename a symbol or go to its definition. The same rename and definition navigation features are available when you install the TypeScript for Visual Studio 2012 plugin.

The TypeScript editor displaying a context menu that allows you to rename a symbol
Figure 5: The TypeScript editor displaying a context menu that allows you to rename a symbol.

Keywords for Type Annotations

TypeScript supports the following keywords for type annotations to establish the intended contract of functions, variables, and properties:

  • any: References the Any type. It represents any JavaScript value and it is a supertype of all types.
  • bool: References the Boolean primitive type.
  • number: References the Number primitive type that represents a double-precision 64-bit format IEEE 754 floating-point value.
  • null: This literal references the only possible value of the Null type. The Null type is a subtype of all types (except Void and Undefined). It isn't possible to explicitly reference the Null type and you can only use the null literal.
  • string: References the String primitive type that represents sequences of characters stored as Unicode UTF-16 code units.
  • undefined: This is the value given to uninitialized variables. The Undefined type is a subtype of all types. It isn't possible to explicitly reference the Undefined type.
  • void: This keyword references the Void type. It is the return type for functions that return no value and the only possible value of the Void type is undefined.


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