An Introduction to TypeScript

TypeScript is was first released by MicroSoft in 2012, so it's relatively new. It is a superset of JavaScript. All legal JavaScript is also legal TypeScript, so knowing TypeScript doesn't excuse you from knowing JavaScript.

however, if you are used to a classical, class based environment with type safety and decorators, TypeScript might be the tool for you.

Features

On top of JavaScript it also gives us features like:

  • Optional strong typing, with compile time errors if we mess up.
  • Classes (which are sugar for a special case of Prototypical inheritance).
  • Decorators - which are fabulously powerful.

We can have start to have a play with TypeScript in Microsoft's TypeScript playground. It gives us real time compilation, so we can see how to make things.

Classes

Let's start with a class. Here's a Toaster:

class Toaster {}

This compiles to a little JavaScript IIFE which generates the newable function and returns it:

var Toaster = (function () {
function Toaster() {
}
return Toaster;
}());

We use the new keyword to make a new object using the Toaster constructor, like so:

var myToaster = new Toaster();

Exercise - Create a class

Visit the TypeScript playground here:

http://www.typescriptlang.org/Playground

Now create a your own simple class. Take a look at the code that is generated. Use new to make a new object.

Attributes

JAvaScript objects are just Hashmaps, and so we can set any attributes we like on them. TypeScript gives us compile time safety, we can choose what attributes we want people to write to.

Say we do this:

class Toaster {}
var myToaster = new Toaster();
myToaster.bread = "Artisan rye splashed with swan's breath"

We get an error. Property bread does not exist on type Toaster.

This is a compile time error. The generated JavaScript will of course run just fine.

We tell the compiler to expect a bread attribute like so:

class Toaster {
bread
}

The error is now gone.

Exercise - Attributes

Give your new object an attribute. Create an instance using the new keyword. Check out the intellisense.

Constructors

A constructor function allows us to configure the new object. Here's our toaster with a constructor function. This constructor gets bread, saves it in an attribute, and console.logs it.

Note that we need to declare the bread attribute:

class Toaster {
bread
constructor(bread) {
this.bread = bread
console.log('Toast was made with bread', bread)
}
}

This compiles to the following. The constructor becomes the newable function returned from the IIFE:

var Toaster = (function () {
function Toaster(bread) {
this.bread = bread;
console.log('Toast was made with bread', bread);
}
return Toaster;
}());

We also have a shorthand for creating public parameters. We can set the paramter to public, and it will create the attribute for us.

class Toaster { constructor(public bread) {} }

Exercise - Constructors

Visit the TypeScript playground here:

http://www.typescriptlang.org/Playground

Add a constructor function to your class. See how it changes your JavaScript. Have your constructor receive a value and save it in an attribute.

Check out the public setting for the parameter.

Use new to create an object. Notice the intellisense as you interact with your new object.

Strong Typing

TypeScript gives us optional Strong Typing, like so:

class Toaster {
constructor(public bread:Bread) {}
}

Our Toaster will now only receive bread. If we try to pass it something else, the compiler will complain (though of course the generated code will still run.)

To make this work, we now need to declare Bread:

class Bread {}

Exercise - Strong Typing

Apply some strong typing to a constructor argument. Add in classes to make the compiler happy. Check out the code you get.

Gulp

Gulp is a development automation tool. It's the successor to Grunt.

We configure gulp using a gulpfile. Our gulpfile contains a set of tasks that we would like to automate. Each task is a stream of activities, for example a js task might:

  1. Compile your code from TypeScript to JavaScript
  2. Reload your web browser so you can see the changes.
  3. Minify.
  4. Save the minified code as app.min.js.

Gulp streams

Gulp has a concept of streams. A stream is a set of files that can be transformed from one form into another.

We create a stream using gulp.src, then pipe it through different functions which can modify the stream in a variety of ways. We can optionally pipe our stream back out onto the filesystem at any point using gulp.dest.

We use gulp for:

  • Compilation
  • Validation
  • Concatenation
  • Reformatting
  • Transformation and transclusion
  • Renaming
  • Wrapping content
  • Anything else we can think of

Gulp modules

We extend the capabilities of Gulp using modules, which are installed using npm. Here are some useful ones:

  • jshint - JavaScript validation
  • sass - CSS precompilation
  • Uglify - JavaScript minification
  • Concat - Script concatenation
  • Autoprefixer - Automatically add vendor prefixes to CSS
  • Header - Adds a header to the file
  • Size - Outputs the size of a minified file

Validating code

A common requirement is to validate our JavaScript. We can do this with a simple Gulp task:

var gulp = require('gulp'),
jshint = require('gulp-jshint');
gulp.task('assets:js', function () {
return gulp.src(components.js)
.pipe(jshint())
.pipe(jshint.reporter('default'))
}

We execute this task with:

gulp assets:js

Automatic execution

We can tell gulp to watch our filesystem for changes, and execute a task whenever a file is modified.

gulp.task('watch', function() {
gulp.watch(components.js, ['assets:js']);

Now we might create a default gulp task:

gulp.task('default', [
'watch'
]);

We can now set our gulp task running simply by typing gulp at a command line.

gulp

Exercise - JSHint

Install Gulp and the gulp-cli using npm. Note that currently gulp has to be installed locally in your project, so we omit the -g flag.

npm install gulp
npm install gulp-cli -g

Test your installation:

gulp --version

Now we're going to set up gulp to validate our javascript.

first install the gulp-jshint dependency

npm install gulp-jshint

Now create a gulpfile containing something like the following:

var gulp = require('gulp'),
jshint = require('gulp-jshint');
gulp.task('js', function () {
return gulp.src('js/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
}

Now run gulp js to execute the task:

gulp js

Any errors? You may need to introduce an error to see the effect.

Set up Gulp to automatically validate the code in your node server. When you save the file, it should give you an error if you have made a mistake.

Piping out a stream

We can make transformations to our code right in the stream, and then at any point, pipe it out into a file. We might pipe it out more than once if we want to.

var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
gulp.task('js', function () {
return gulp.src('./js/**/*.js')
.pipe(concat('app.js'))
.pipe(gulp.dest('./build/js'))
.pipe(rename('app.min.js'))
.pipe(uglify())
.pipe(gulp.dest('./build/js'))
});

Exercise - Pipe out

Try to get the above running. Make a gulp task that will concatenate and minify your JavaScript.

Remember you will need to npm install gulp-concat and gulp-uglify.

Now integrate this with the lint exercise above. Make a task that will first lint your code, then concat and minify.

Angular Exercise - ngAnnotate

ngAnnotate is a project that will convert Angular round brace injectors into minification safe square brace injectors.

Here's the gulp task: https://www.npmjs.com/package/gulp-ng-annotate

Try to integrate ngAnnotate into your js build process.

Exercise - Header

You might wish to mark your generated files as such so that future coders don't try to edit them directly. We can use gulp-header for this.

https://www.npmjs.com/package/gulp-header

Use gulp-header to add a header to your concatenated js file, something like this:

"Generated by `gulp js`
// Do not modify
"

Exercise - Validate your gulpfile

Slightly meta this one. Use the gulp-jsonlint package to automatically validate your gulpfile.