Since the TypeScript language is a strict superset of JavaScript, all the repetitive tasks like minification, compilation, unit testing, linting, etc, performed by Grunt can also be applied to TypeScript projects.
This post describes how to add TypeScript to an AngularJS project where task automation is performed by Grunt.
Grunt processes a task automation pipeline defined in a Gruntfile. A sample Gruntfile is available from the Grunt website.
A more sophisticated Gruntfile, with reasonable defaults and best practises, is generated by Yeoman through generator-angular.
To make it easier to follow along, I will remove all globally installed npm modules on my machine:
# http://stackoverflow.com/a/9283646/467754 npm -g ls | grep -v 'npm@' | awk '/@/ {print $2}' | awk -F@ '{print $1}' | xargs npm -g rm # There are no globally installed npm modules: npm list -g C:\Users\Nikos\AppData\Roaming\npm L-- (empty)
Install generator-angular:
npm install -g generator-angular # The following higher-level npm modules are globally installed: npm list -g -depth=0 C:\Users\Nikos\AppData\Roaming\npm ├── bower@1.3.1 ├── generator-angular@0.8.0 ├── generator-karma@0.7.0 ├── grunt-cli@0.1.13 └── yo@1.1.2
Setting up a new AngularJS project through generator-angular generates all the boilerplate including the task automation pipeline (Gruntfile).
yo angular [app-name]
In case of any npm installation errors run 'npm cache clean [-g]'.
Install a karma adapter, as well as a browser launcher:
npm install karma-jasmine --save-dev npm install karma-chrome-launcher --save-dev
Invoke Grunt via 'grunt serve' and modify a test file. Any modification in the test files invokes Karma.
Install the command-line TypeScript compiler:
npm install -g typescript # The following higher-level npm modules are globally installed: npm list -g -depth=0 C:\Users\Nikos\AppData\Roaming\npm ├── bower@1.3.1 ├── generator-angular@0.8.0 ├── generator-karma@0.7.0 ├── grunt-cli@0.1.13 ├── typescript@0.9.7 <-- └── yo@1.1.2
Install grunt-typescript:
npm install grunt-typescript --save-dev
Rename all files with a .js
extension to have a .ts
extension and modify the Gruntfile:
typescript: { base: { src: ['<%= yeoman.app %>/scripts/{,*/}*.ts'], options: { target: 'es5', sourceMap: true } }, test: { src: ['test/spec/{,*/}*.ts'], options: { target: 'es5', sourceMap: true } } }, ... ts: { files: ['<%= yeoman.app %>/scripts/{,*/}*.ts'], tasks: ['typescript'] }, tsTest: { files: ['test/spec/{,*/}*.ts'], tasks: ['typescript:test'] },
The file comparison output should be similar with the image shown below:
Remove the indentation setting from JSHint since TypeScript indents code idiomatically.
Most, if not all, of the TypeScript declaration source files are available by installing DefinitelyTyped:
bower install DefinitelyTyped --save-dev
Create an _all.ts
declaration source file containing each necessary declaration:
/// <reference path='../bower_components/DefinitelyTyped/angularjs/angular.d.ts' /> /// <reference path='controllers/main.ts' /> /// <reference path='app.ts' />
The '_all.ts' declaration source file is a convenient way of referencing all declaration sources in one line:
/// <reference path='[relative-path-to-all.ts-file]' />
A similar pattern can be applied to the test files:
/// <reference path='../../app/bower_components/DefinitelyTyped/angularjs/angular-mocks.d.ts' /> /// <reference path='../../app/bower_components/DefinitelyTyped/jasmine/jasmine-1.3.d.ts' /> /// <reference path='../../app/scripts/controllers/main.ts' />
The TypeScript language services is available as an official add-in for Visual Studio as well as an unofficial, but rather excellent, add-in for Sublime Text.