TypeScript is a new Microsoft offering that seeks to change the way we write JavaScript. As the name implies, TypeScript associates a strongly typed layer in conjunction with JavaScript. TypeScript also associates an object-oriented layer with JavaScript.
Find additional: JavaScript Articles
If you are experienced with JavaScript, you know that it is neither strongly typed nor object oriented. Rather, JavaScript is a dynamic language that is functional in nature. For the C# or Visual Basic Developer, there can be significant challenges with JavaScript such as defining interfaces and classes, declaring integers, strings, and other variables, and enforcing that integrity.
In JavaScript, you don't define classes and interfaces. Rather, objects are declared and through prototyping, object-oriented inheritance can be achieved. Every variable is defined with the var keyword. A variable can easily mutate from string to integer to date. In JavaScript, you can declare a function that does not take arguments and call that function with arguments.
None of this is to say that through JavaScript you can't enforce rules via custom code. With TypeScript, you can write declarative code to enforce rules. For example, if a variable is supposed to be a string, you can declare it as such in TypeScript. There is no such strong typing with JavaScript. If your code attempts to assign an integer value to that same variable, the TypeScript Compiler catches and reports that error. That's an experience C# and Visual Basic developers can relate to, where the compiler caught such type mismatch errors. Pure JavaScript does not catch such an error until the code is executed, (assuming the operation you were employing could only be performed on a string). In this article, I will introduce you to simple examples that will help you get started with TypeScript.
Do You Really Need TypeScript?
You may be thinking that TypeScript is just syntactic sugar that compiles to JavaScript and that you should just stick to and learn JavaScript. Remember: TypeScript IS NOT a replacement for JavaScript.
TypeScript compiles to pure JavaScript but that isn't a license for ignorance of how JavaScript works. The code that ultimately runs is pure JavaScript, and for that reason, you still need to understand how JavaScript works. When you are ready to take the plunge, I highly recommend the book “Secrets of the JavaScript Ninja” by John Resig and Bear Bibeault from Manning Publications. Be forewarned, the book is not a light read. It's an exhaustive study of what JavaScript really is and how it really works.
Getting back to the question of TypeScript, if you already know and are comfortable with JavaScript, do you need TypeScript? The answer is: No. The real question is whether you should use TypeScript? As is often the case, the answer is: It depends.
TypeScript affords you the opportunity to write less direct JavaScript code. TypeScript also affords you the opportunity to write code that is more easily understood by the JavaScript uninitiated. If you are leading a team, when considering tools like TypeScript, it may be more helpful to take yourself and your own preferences out of the equation. Simulating object orientation in JavaScript can involve writing more code. TypeScript can reduce that burden, because types can be declared in TypeScript; you don't have to write specific JavaScript code to validate data types and to simulate class structures and inheritance.
With that in mind, although you may not need TypeScript, it may be well worth exploring because there may be benefits that accrue to the team as a whole. Chances are good that your team's predominant language is either C# or Visual Basic, and JavaScript is quite different from those two environments. TypeScript is an attempt to bridge those differences without sacrificing JavaScript's true power. TypeScript allows developers to use their object oriented programming skills directly to produce better JavaScript.
TypeScript allows developers to use their object oriented programming skills directly to produce better JavaScript.
Downloading and Installing TypeScript
The online home for TypeScript is typescriptlang.org. There, you will have ready access to tutorials, samples and downloads. If you are working in Visual Studio, the best option for you to install TypeScript is to download the plugin. Figure 1 illustrates the TypeScript Download Page, which offers several download options.
Once you have downloaded and installed TypeScript, you can verify your installation by opening the command prompt and typing tcs, which is the command to run the TypeScript compiler. Figure 2 illustrates how your results should appear if you successfully installed TypeScript.
Creating Your First TypeScript File
TypeScript source code files require either a .ts or a .d.ts extension. Here is the code for the first TypeScript file:
// setBackgroundColor.ts.
function setBackgroundColor() {
document.body.style.backgroundColor = "rgb(255,0,0)";
}
setBackgroundColor();
It looks just like JavaScript. That's because it is JavaScript! You might consider TypeScript to be a superset of JavaScript. That means you can include both pure JavaScript and the declarative features in TypeScript in your TypeScript files. In this example, the TypeScript file is named setBackgroundColor.ts
.
Figure 3 illustrates how to compile the TypeScript file. The result is a JavaScript file with the same name, in this case setBackgroundColor.js
.
The ts and js files are identical because the ts file was pure JavaScript without any specific TypeScript syntax. Figure 4 illustrates the ts and js files.
When your ts file is pure JavaScript, the resulting js file is identical to the ts file.
Would you ever want to just create TypeScript files and let the compiler create your js files? You may want to consider this, given the fact that your js file is the result of code compilation. Normally, we work directly with js files. Consider this invalid JavaScript:
function setBackgroundColor() {
document.body.backgroundColor = "rgb(255,0,0)";
}
setBackgroundColor();
There is no body property called backgroundColor
. Granted, you could fiddle with the HTMLElement
object's prototype and create a custom property, but that is beyond the scope of this article. If you wrote it in JavaScript, assuming after you didn't catch the mistake, you would have to run the code to see the error. Or perhaps you have a set of tests that validates your JavaScript code's side effects. Or, you could use TypeScript. Figure 5 illustrates the compiler error.
Creating TypeScript Classes
With TypeScript, unlike native JavaScript, there is a native class keyword. The following snippet illustrates a simple TypesScript class definition:
class Person {
fullname : string;
constructor(public firstname, public middleinitial, public lastname) {
this.fullname = firstname + " " + middleinitial + " " + lastname;
}
}
There is one public member, fullname
, and there is a public constructor that accepts three arguments: first, middle and last name. Within that constructor, the arguments are assembled and the result is used to hydrate the public fullname
member.
The compiled JavaScript looks a bit different:
var Person = (function () {
function Person(firstname, middleinitial, lastname)
{
this.firstname = firstname;
this.middleinitial = middleinitial;
this.lastname = lastname;
this.fullname = firstname + " " + middleinitial
+ " " + lastname;
}
return Person;
})();
The resulting JavaScript listed immediately below is more verbose. Unlike what the TypeScript file specified, the JavaScript code creates a Person
object with four public members, firstname
, middlename
, lastname
and fullname
. The resulting JavaScript could be simplified to:
var Person = (function () {
function Person(firstname, middleinitial, lastname)
{
this.fullname = firstname + " " + middleinitial + " " + lastname;
}
return Person;
})();
The TypeScript code articulates the code's intent better than JavaScript. Couple that with the fact that the TypeScript compiler catches things that otherwise would only be caught at runtime, and TypeScript is starting to look very appealing.
Creating TypeScript Interfaces
The interface concept does not exist in JavaScript because JavaScript is a dynamic un-typed functional language. An interface specifies a contract, something that is at odds with a language like JavaScript. But just because a language doesn't natively support the notion of classes, interfaces, and strong typing, it doesn't mean that you don't want your code to enforce such things as if these were native language features.
Continuing with our Person class, let's expand the sample with a simple interface:
class Person {
fullname : string;
constructor(public firstname, public middlename, public lastname) {
this.fullname = firstname + " " + middlename + " " + lastname;
}
}
interface IPerson {
fullname: string;
}
function displayPerson(person : IPerson) {
return "Hello, " + person.fullname;
}
In this example, an interface called IPerson
has been created. IPerson
has one public member: fullname
. Notice that the function displayPerson
is a single argument that is bound to the IPerson
interface. If your code references any property on the Person
argument other than what has been publically exposed in the IPerson
interface, the TypeScript compiler reports an error. To illustrate, let's assume that we modified the displayPerson
function to display the first name:
function displayPerson(person : IPerson) {
return "Hello, " + person.firstname;
}
Figure 6 illustrates the compilation error that is encountered.
With TypeScript, you can also create variables based on the interfaces, just like in C#:
var myPerson : IPerson;
Working with Property Cccessors
In C# and Visual Basic, the concept of property getters and setters is well known and long established. In JavaScript, it is a new concept, introduced in ECMAScript 5. ECMAScript is the standard upon which JavaScript is based. (For more details on ECMA and the evolving standard, navigate to ecmascript.org. )
To illustrate the property getters and setters, consider this slightly modified version of the Person
class:
class Person {
private _fullname : string;
constructor(public firstname, public middlename, public lastname) {
this._fullname = firstname + " " + middlename + " " + lastname;
}
get fullname() {
return this._fullname;
}
}
Instead of the fullname
property being directly exposed, it is now exposed through a get function called fullname()
. Because this feature must be targeted to ECMAScript 5-compliant code, you must supply the correct complier directive:
<tsc --target ES5 getterexample.ts
The following is the JavaScript produced:
var Person = (function () {
function Person(firstname, middlename, lastname) {
this.firstname = firstname;
this.middlename = middlename;
this.lastname = lastname;
this._fullname = firstname + " " + middlename + " " + lastname;
}
Object.defineProperty(Person.prototype, "fullname",
{
get: function () {
return this._fullname;
},
enumerable: true,
configurable: true
});
return Person;
})();
As previously observed, the TypeScript compiler creates firstname
, middlename
, and lastname
members. These items can be safely removed. If, for some reason, there was TypeScript code that attempted to access the firstname
, middlename
, or lastname
directly, TypeScript reports an error since there is no public interface for these properties.
Visual Studio Integration
Although the command prompt option is good to know, more than likely, you will interact with TypeScript in the Visual Studio IDE. From the IDE, the compilation of your TypeScript files can be automatic. In order to get the full experience, you need to make sure you have downloaded and installed the Web Essentials plug-in. Figure 7 illustrates the Extensions and Updates dialog from where the plug-in can be installed.
Once you have everything installed in Visual Studio, you can add a new TypeScript file. This step is illustrated in Figure 8.
The default TypeScript template, illustrated in Figure 9, contains sample code. For TypeScript files, there is a dual pane. The left pane is the TypeScript file. The right pane, which is read only, is the compiled JavaScript code. Note the Module
keyword that translates into a JavaScript namespace. As you modify the TypeScript code, the JavaScript code is updated to reflect those changes. Also note that minified and non-minified JavaScript files are created.
Conclusion
This article only scratches the surface of what TypeScript offers. Nevertheless, you have a good basis to decide whether or not TypeScript is something you would want to implement in your personal development toolkit. Compiling JavaScript so that syntax errors can be caught before runtime is very appealing. This is a big benefit for an automated build and continuous integration environment. TypeScript allows developers to use C#-like syntax to allow you to interact with JavaScript in an OOP manner may make it easier for those with little JavaScript experience to embrace and adopt the language. Although TypeScript compiles to pure JavaScript, there is still an absolute requirement that if you are going to use JavaScript, you still need to learn how it works on its own terms.