TypeScript as a language for Angular applications

The reason is that developing in JavaScript isn’t overly productive. Say a function expects a string value as an argument, but the developer mistakenly invokes it by passing a numeric value. With JavaScript, this error can be caught only at run- time. Java or C# compilers won’t even compile code that has mismatching types, but JavaScript is forgiving because it’s a dynamically typed language.

On larger projects, good IDE context-sensitive help and support for refactoring are important. Renaming all occurrences of a variable of function name in spatially typed languages is done by IDEs in a split second, even in projects that have thousands oaf lines of code; but this isn’t the case in JavaScript, which doesn’t support types. IDEs can help with refactoring much better when the types of the variables are known.

To be more productive, you may consider developing in a statically typed language and then convert the code to Javascript for deployment. Currently there are dozens of languages that compile to JavaScript. The most popular are TypeScript, CoffeeScript, and Dart.

Why not use the Dart language?

  • Interoperability with third-party Javascript libraries isn’t that great.
  • Development in Dart can be done only in a specialized version of the Chrome browser (Dartium) that comes with the Dart VM.
  • The generated JavaScript isn’t easily readable by a human.
  • The community of Dart developers is rather small.

Why write Angular apps in TypeScript?

You can write applications in ES6 (and even in ES5), but we use TypeScript as a substantially more productive way for writing JavaScript. Here’s why:

  • TypeScript supports types.
  • Great IDE support is one of TypeScript’s main advantages.
  • Angular is bundled with type-definitions files, so IDEs perform type checking while using the Angular API and offer context-sensitive help right out of the box.
  • TypeScript follows the ECMAScript 6 and 7 specifications and adds to them types, interfaces, decorators, class member variables (fields), generics, and the keywords public and private.
  • TypeScript interfaces allow you to declare custom types that will be used in your application.
  • The generated JavaScript code is easy to read, and it looks like hand-written code.
  • Most of the code samples in angular documentation, articles, and blogs are given in TypeScript.

The role of transpilers

Transpiling means converting the source code of a program in one language into source code in another language. Many developers prefer to use the word compiling, so phrases like “TypeScript compiler” and “compile TypeScript into JavaScript” are also valid.

Getting start with TypeScript

Installing and using the TypeScript compiler

The TypeScript compiler is itself written in TypeScript. You’ll use Node.js’s nom package manager to install the compiler.

npm install -g typescript

To check the version of your TypeScript compiler, run the following command:

tsc --version

Code written in TypeScript has to be transpiled into JavaScript so web browsers can execute it. The following command will transpire main.ts into main.js.

tsc main.ts

You can also generate source map files that map the source code in TypeScript to the generated JavaScript. With source maps, you can place breakpoints in your TypeScript code while running it in the browser, even though it executes JavaScript. To compile main.ts to main.js while also generating the main.map source map file, you run the following command:

tsc --sourcemap main.ts

During compilation, TypeScript’s compiler removes all TypeScript types, interfaces, and keywords from the generated code to produce valid JavaScript. By providing compiler options, you can generate JavaScript compliant with ES3, ES5, or ES6 syntax.

tsc --t ES5 main.ts

Transpiling TypeScript in a web browser

During development, we use tic installed locally, but transpiring can also be done either on the server during development or on the fly when the web browser loads your application. In this book, we use the SystemJS library, which internally use tsc to transpile and dynamically load app modules.

Keep in mind the transpiling on the fly in the browser may introduce delays in displaying your app’s content on the user’s device. If you use SystemJS to load and transpile your code in the browser, source maps will be generated by default.

If you want to compile your code in memory without generating output .js files, run tic with the —noEmit option. We often use this option in development mode because we just need to have executable JavaScript code in the browser’s memory.

You can start your TypeScript compiler in watch mode by providing the -w option. In this mode, whenever you modify and save your code, it’s automatically transpiled into the corresponding JavaScript files. To compile and watch all .ts files, run the following command:

tsc -w *.ts

The compiler will compile all the TypeScript files, print error messages (if any) on the console, and continue watching the files for changes. As soon as a file changes, tic will immediately recompile it.

Note Typically, we don’t use the IDE to compile TypeScript. We use either SystemJS with its in-browser compiler or a bundler (Webpack) that uses a special TypeScript loader for compilation.

The TypeScript compiler allows you to preconfigure the process of compilation (specifying into the source and destination directories, source map generation, and so on). Thee presence of the tsconfig.json configuration file in the project directory means you can enter tic on the command line, and the compiler will read all the options from tsconfig.json. A sample tsconfig.json file is shown here.

// Listing B.1 tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "rootDir": ".",
    "outDir": "./js"
  }
}

This config file instructs tsc to transpile the code into ES5 syntax. The generated JavaScript files will be located in the js directory. The tsconfig.json file may include the files sections that lists the files that have to be compiled by TypeScript. Listing B.1 doesn’t include this list because you use the rootDir option to request the compilation of all files starting from the root directory of the project.

If you want to exclude some of your project’s files from compilation, add the exclude property to tsconfig.json. This is how you can exclude the entire content of the node_modules directory:

"exculde": [
  "node_modules"
]

You can read more about configuring the compilation process and the TypeScript compiler’s options at in the TypeScript documentation.

Note Most of the Angular examples in the book use annotations (a.k.a. decorators) with classes or class members (such as @Component and @Input). Annotations are a way to add metadata to the annotated classes or their members.


TypeScript as a superset of JavaScript

TypeScript fully supports ES5 and most of the ES6 syntax. Just change the name extension of a file with JavaScript code from .js to .ts, and it’ll become valid TypeScript code. The only two exceptions we’ve seen so far are handling optional function parameters and assigning a value to an object literal.

In JavaScript, even if a function is declared with two parameters, you can invoke it by providing only one, whereas in TypeScript you need to append a question mark to the parameter name to make it optional. In JavaScript, you can initialize a variable with an empty object literal and immediately attach a property using dot notation, whereas in TypeScript you’d need to use square brackets.

But these differences are minor. What’s more important is that because its’ superset of JavaScript, TypeScript adds a number of useful features to JavaScript.

Tip If you’re in the middle of converting a JavaScript project to TypeScript, you can use the tsc compiler’s —allowJs option. The TypeScript compiler will check the input.js files for syntax errors and emit valid output based on the —target and —moudle options of tsc. The output can be combined with other .ts files as well. Source maps are still generated for .js files, just as with .ts files.


Optional types

You can declare variables and provide types of all or some of them. The following two lines are valid TypeScript syntax:

var name1 = 'John Smith'
var name2: string = 'John Smith'

Classes

If you have Java or C# experience, you’ll be familiar with the concepts of classes and inheritance in their classical form. In those languages, the definition of a class is loaded in memory as a separate entity (like a blueprint) and is shared by all instances of this classes. If a class is inherited from another one, the object is instantiated using the combined blueprint of both classes.

TypeScript is a superset of JavaScript, which only supports prototypal inheritance, where you can create an inheritance hierarchy by attaching one object to the prorototype property of another. In this case, an inheritance (or rather, a linkage) of objects is created dynamically.

In TypeScript the class keyword is syntactic sugar to simplify coding. In the end, your classes will be transpiled into JavaScript objects with prototypal inheritance. In TypeScript, you can declare a constructor function and instantiate it with the new keyword.

A class can include a constructor, fields (a.k.a. properties), and methods. Properties and methods declared are often referred as class members. We’ll illustrate the syntax of TypeScript classes by showing you a series of code samples and comparing them with the equivalent ES5 syntax.

Let’s create a simple Person class that contains four properties to store the first and last name, age, and Social Security number (a unique identifier assigned to every legal resident of the United States).

// TypeScript version
class Person {
  firstName: string
  lastName: string
  age: number
  ssn: string
}

var p = new Person()

p.firstName = "John"
p.lastName = "Smith"
p.age = 20
p.ssn = "112-90-4567"
// JavaScript closure generated by the tsc compiler.
var Person = (function () {
  function Person() {
  }
  return Person
})()
var p = new Person()
p.firstName = "John"
p.lastName = "Smith"
p.age = 29
p.ssn = "112-90-4567"

By creating a closure for the Person function, the TypeScript compiler enables the mechanism for exposing and hiding the elements of the Person object.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.