TypeScript

How and when you might use TypeScript in Drupal

You might have heard of this cool new thing called TypeScript. If not, do not despair. Here is a quick explanation.

Straight from the horse’s mouth, TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Which means what you are actually running in the browser or in node is actually still JavaScript. You are just writing it in TypeScript.

The benefits of using TypeScript

So when should one use TypeScript? Or for that matter any statically typed language. Well if the only thing you are producing is small, short lived prototypes that are supposed to be throwaways afterwards I wouldn’t go for TypeScript. It might initially slow you down a whole bunch. If you on the other hand need to ship something to a customer, it has to be long lived and multiple people need to be working on it, I would proclaim TypeScript to be the antidote for some of the many pains web developers endure.

The goal of TypeScript is to add a static type system to a place where it doesn’t exist. The benefits of a statically typed language are a bit outside the scope of this post, but a quick summarization of the most common perceived benefits are as listed below:

  • Reduces the amount of errors.
  • Makes efficient code completion.
  • Greater ability to refactor with confidence.
  • Lesser mental burden on the programmer.
  • Code becomes self documenting.

A quick search on the world wide web will reveal even more benefits, but also some of the many drawbacks a statically typed language might offer. With that said, the above list of benefits seems like a good addition to most applications. So let’s take a look at how we decided to make use of TypeScript with a Drupal 8 installation at Reload.

Using TypeScript in an existing code base

Besides the above mentioned benefits we also had another sub goal. We wanted the TypeScript implementation to be in an existing code base and to be as noninvasive as possible. We wanted to keep our working JS code while new code could be written in TypeScript. If it ain’t broke don’t fix it. So if you deem TypeScript a worthy pursuit and a good investment follow along below!

So onto the practical side of things.
Getting the TypeScript compiler up and running shouldn't pose much of a problem. You need to have Node.js and npm available on your machine and that’s more or less it.

Install TypeScript with:

npm install -g typescript

When you have that all you need to do is make a app.ts file, point the compiler at it and outcomes an app.js file you can run in either your browser or with Node.js.
 

function hello(name: string) {
 return 'Hello ' + name
}

console.log(hello('Jimmy'))

tsc ./app.ts // transpiles and outputs an app.js file in the same directory as app.ts.

node app.js // executes our small program.

So now we have seen that running the TypeScript compiler actually just produces a JavaScript file that can be run in any environment that supports JavaScript, be it the browser or Node.js.

Configuring TypeScript in Drupal

The boring but rather useful last part of this post is how to configure TypeScript for our Drupal 8 application. The boring part being configuration, not Drupal. The confusing answer to this is that you can do it a couple different ways.

The most basic and simple setup would be to have a directory with your TypeScript files and an output directory for the transpiled JS files. When dealing with multiple ts files and likely nested directories of ts files we need a tsconfig.json file at the root of our project. In our case for this Drupal 8 site we want it at the root of our custom theme directory.

{
 "compilerOptions": {
   "rootDir": "./ts",
   "outDir": "./assets"
 }
}

The above configuration is pretty simple and self explanatory, but without both of them the TypeScript compiler wouldn’t know where to go looking for ts files and where to output them.

To transpile your ts files all you need to do now is run tsc in the same directory your config file is in and you will end up with a folder that has all of your transpiled ts files in plain js.

There are many more configurations you might want and need to set up when using TypeScript, but we’ll stick with this for now in the name of simplicity.

You could use this as it is. The only thing you would need to make sure to avoid is to have a plain js files named the same as a ts file because the compiler would overwrite the js file when executing. Make the tsc command part of your build script and you should be good to go with this.

Consider your pipeline setup

Most of the time the world and our projects aren’t as simple as what I just described. You probably already have a pipeline setup consisting of either grunt, gulp, webpack, rollup, parcel etc.

One of the more common pipeline setups in the Drupal community is gulp. Below we’ll go through how we implemented TypeScript into our gulp pipeline.

You’ll need to install the plugin gulp-typescript in addition to the typescript package itself.

npm install gulp-typescript typescript --save-dev

In your gulpfile, require the gulp-typescript package and create a new task for it.
 

const ts = require('gulp-typescript')

const tsProject = ts.createProject('tsconfig.json')

gulp.task('typescript', function() {
 const tsResult = gulp
   .src(tsProject.src()) // pointing to our tsconfig.json configuration for what files to load.
   .pipe(tsProject()) // compilation/transpilation
 return tsResult.js.pipe(gulp.dest('assets')) // the actual destination of the final js files.
})

Pretty simple stuff right? You might run into an issue with your version of Node.js if you are on a really old one. We did. TypeScript has great backwards compatibility, but the gulp-typescript package requires a minimum version of Node.js 8.

Add this task to your watch, production, etc. scripts and you are good to go.

A rude awakening

So should you re-write or even just copy paste all of your existing working Drupal JavaScript code and make it into TypeScript? The answer is probably no. For our own test with this setup I decided to take our existing gallery implementation and port it to TypeScript. A bit of clean-up and typing later I was done, tested and shipped.

An hour later our chat was burning. The gallery wasn’t working. “But it’s type safe and ran through the pipeline perfectly?”. We had missed the situation where there is more than one gallery on a page.

This example is just to underline that TypeScript is not a silver bullet. It does make for a nicer developer experience and squashes a specific breed of bugs, but it doesn’t provide you with functioning features out the box. You have to provide that.

Godspeed 

I hope this pragmatic walkthrough was enlightening to you, dear reader.

For us at Reload the delve into TypeScript on different projects have been rewarding and a great learning experience. Hopefully you will find it equally as awesome as we do.

Additional TypeScript information can be found here.