Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
TypeScript Design Patterns
TypeScript Design Patterns

TypeScript Design Patterns: Boost your development efficiency by learning about design patterns in TypeScript

eBook
Can$30.99 Can$44.99
Paperback
Can$55.99
Subscription
Free Trial

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

TypeScript Design Patterns

Chapter 1. Tools and Frameworks

We could always use the help of real code to explain the design patterns we'll be discussing. In this chapter, we'll have a brief introduction to the tools and frameworks that you might need if you want to have some practice with complete working implementations of the contents of this book.

In this chapter, we'll cover the following topics:

  • Installing Node.js and TypeScript compiler
  • Popular editors or IDEs for TypeScript
  • Configuring a TypeScript project
  • A basic workflow that you might need to play with your own implementations of the design patterns in this book

Installing the prerequisites

The contents of this chapter are expected to work on all major and up-to-date desktop operating systems, including Windows, OS X, and Linux.

As Node.js is widely used as a runtime for server applications as well as frontend build tools, we are going to make it the main playground of code in this book.

TypeScript compiler, on the other hand, is the tool that compiles TypeScript source files into plain JavaScript. It's available on multiple platforms and runtimes, and in this book we'll be using the Node.js version.

Installing Node.js

Installing Node.js should be easy enough. But there's something we could do to minimize incompatibility over time and across different environments:

  • Version: We'll be using Node.js 6 with npm 3 built-in in this book. (The major version of Node.js may increase rapidly over time, but we can expect minimum breaking changes directly related to our contents. Feel free to try a newer version if it's available.)
  • Path: If you are installing Node.js without a package manager, make sure the environment variable PATH is properly configured.

Open a console (a command prompt or terminal, depending on your operating system) and make sure Node.js as well as the built-in package manager npm is working:

$ node -v
6.x.x
    
$ npm -v
3.x.x

Installing TypeScript compiler

TypeScript compiler for Node.js is published as an npm package with command line interface. To install the compiler, we can simply use the npm install command:

$ npm install typescript -g

Option -g means a global installation, so that tsc will be available as a command. Now let's make sure the compiler works:

$ tsc -v

Version 2.x.x

Note

You may get a rough list of the options your TypeScript compiler provides with switch -h. Taking a look into these options may help you discover some useful features.

Before choosing an editor, let's print out the legendary phrase:

  1. Save the following code to file test.ts:
    function hello(name: string): void { 
            console.log(`hello, ${name}!`); 
          } 
           
          hello('world'); 
    
  2. Change the working directory of your console to the folder containing the created file, and compile it with tsc:
          $ tsc test.ts
    
  3. With luck, you should have the compiled JavaScript file as test.js. Execute it with Node.js to get the ceremony done:
    $ node test.js
    hello, world!
    

Here we go, on the road to retire your CTO.

Choosing a handy editor

A compiler without a good editor won't be enough (if you are not a believer of Notepad). Thanks to the efforts made by the TypeScript community, there are plenty of great editors and IDEs ready for TypeScript development.

However, the choice of an editor could be much about personal preferences. In this section, we'll talk about the installation and configuration of Visual Studio Code and Sublime Text. But other popular editors or IDEs for TypeScript will also be listed with brief introductions.

Visual Studio Code

Visual Studio Code is a free lightweight editor written in TypeScript. And it's an open source and cross-platform editor that already has TypeScript support built-in.

You can download Visual Studio Code from https://code.visualstudio.com/ and the installation will probably take no more than 1 minute.

The following screenshot shows the debugging interface of Visual Studio Code with a TypeScript source file:

Visual Studio Code

Configuring Visual Studio Code

As Code already has TypeScript support built-in, extra configurations are actually not required. But if the version of TypeScript compiler you use to compile the source code differs from what Code has built-in, it could result in unconformity between editing and compiling.

To stay away from the undesired issues this would bring, we need to configure TypeScript SDK used by Visual Studio Code manually:

  1. Press F1, type Open User Settings , and enter. Visual Studio Code will open the settings JSON file by the side of a read-only JSON file containing all the default settings.
  2. Add the field typescript.tsdk with the path of the lib folder under the TypeScript package we previously installed:

    1. Execute the command npm root -g in your console to get the root of global Node.js modules.

    2. Append the root path with /typescript/lib as the SDK path.

    Note

    You can also have a TypeScript package installed locally with the project, and use the local TypeScript lib path for Visual Studio Code. (You will need to use the locally installed version for compiling as well.)

Opening a folder as a workspace

Visual Studio Code is a file- and folder-based editor, which means you can open a file or a folder and start work.

But you still need to properly configure the project to take the best advantage of Code. For TypeScript, the project file is tsconfig.json, which contains the description of source files and compiler options. Know little about tsconfig.json? Don't worry, we'll come to that later.

Here are some features of Visual Studio Code you might be interested in:

  • Tasks: Basic task integration. You can build your project without leaving the editor.
  • Debugging: Node.js debugging with source map support, which means you can debug Node.js applications written in TypeScript.
  • Git: Basic Git integration. This makes comparing and committing changes easier.

Configuring a minimum build task

The default key binding for a build task is Ctrl + Shift + B or cmd + Shift B on OS X. By pressing these keys, you will get a prompt notifying you that no task runner has been configured. Click Configure Task Runner and then select a TypeScript build task template (either with or without the watch mode enabled). A tasks.json file under the .vscode folder will be created automatically with content similar to the following:

{ 
  "version": "0.1.0", 
  "command": "tsc", 
  "isShellCommand": true, 
  "args": ["-w", "-p", "."], 
  "showOutput": "silent", 
  "isWatching": true, 
  "problemMatcher": "$tsc-watch" 
} 

Now create a test.ts file with some hello-world code and run the build task again. You can either press the shortcut we mentioned before or press Ctrl/Cmd + P, type task tsc , and enter.

If you were doing things correctly, you should be seeing the output test.js by the side of test.ts.

There are some useful configurations for tasking that can't be covered. You may find more information on the website of Visual Studio Code: https://code.visualstudio.com/.

From my perspective, Visual Studio Code delivers the best TypeScript development experience in the class of code editors. But if you are not a fan of it, TypeScript is also available with official support for Sublime Text.

Sublime Text with TypeScript plugin

Sublime Text is another popular lightweight editor around the field with amazing performance.

The following image shows how TypeScript IntelliSense works in Sublime Text:

Sublime Text with TypeScript plugin

The TypeScript team has officially built a plugin for Sublime Text (version 3 preferred), and you can find a detailed introduction, including useful shortcuts, in their GitHub repository here: https://github.com/Microsoft/TypeScript-Sublime-Plugin.

Note

There are still some issues with the TypeScript plugin for Sublime Text. It would be nice to know about them before you start writing TypeScript with Sublime Text.

Installing Package Control

Package Control is de facto package manager for Sublime Text, with which we'll install the TypeScript plugin.

If you don't have Package Control installed, perform the following steps:

  1. Click Preferences > Browse Packages..., it opens the Sublime Text packages folder.
  2. Browse up to the parent folder and then into the Install Packages folder, and download the file below into this folder: https://packagecontrol.io/Package%20Control.sublime-package
  3. Restart Sublime Text and you should now have a working package manager.

Now we are only one step away from IntelliSense and refactoring with Sublime Text.

Installing the TypeScript plugin

With the help of Package Control, it's easy to install a plugin:

  1. Open the Sublime Text editor; press Ctrl + Shift + P for Windows and Linux or Cmd + Shift + P for OS X.
  2. Type Install Package in the command palette, select Package Control: Install Package and wait for it to load the plugin repositories.
  3. Type TypeScript and select to install the official plugin.

Now we have TypeScript ready for Sublime Text, cheers!

Like Visual Studio Code, unmatched TypeScript versions between the plugin and compiler could lead to problems. To fix this, you can add the field "typescript_tsdk" with a path to the TypeScript lib in the Settings - User file.

Other editor or IDE options

Visual Studio Code and Sublime Text are recommended due to their ease of use and popularity respectively. But there are many great tools from the editor class to full-featured IDE.

Though we're not going through the setup and configuration of those tools, you might want to try them out yourself, especially if you are already working with some of them.

However, the configuration for different editors and IDEs (especially IDEs) could differ. It is recommended to use Visual Studio Code or Sublime Text for going through the workflow and examples in this book.

Atom with the TypeScript plugin

Atom is a cross-platform editor created by GitHub. It has a notable community with plenty of useful plugins, including atom-typescript. atom-typescript is the result of the hard work of Basarat Ali Syed, and it's used by my team before Visual Studio Code. It has many handy features that Visual Studio Code does not have yet, such as module path suggestion, compile on save, and so on.

Like Visual Studio Code, Atom is also an editor based on web technologies. Actually, the shell used by Visual Studio Code is exactly what's used by Atom: Electron, another popular project by GitHub, for building cross-platform desktop applications.

Atom is proud of being hackable, which means you can customize your own Atom editor pretty much as you want.

Then you may be wondering why we turned to Visual Studio Code. The main reason is that Visual Studio Code is being backed by the same company that develops TypeScript, and another reason might be the performance issue with Atom.

But anyway, Atom could be a great choice for a start.

Visual Studio

Visual Studio is one of the best IDEs in the market. And yet it has, of course, official TypeScript support.

Since Visual Studio 2013, a community version is provided for free to individual developers, small companies, and open source projects.

If you are looking for a powerful IDE of TypeScript on Windows, Visual Studio could be a wonderful choice. Though Visual Studio has built-in TypeScript support, do make sure it's up-to-date. And, usually, you might want to install the newest TypeScript tools for Visual Studio.

WebStorm

WebStorm is one of the most popular IDEs for JavaScript developers, and it has had an early adoption to TypeScript as well.

A downside of using WebStorm for TypeScript is that it is always one step slower catching up to the latest version compared to other major editors. Unlike editors that directly use the language service provided by the TypeScript project, WebStorm seems to have its own infrastructure for IntelliSense and refactoring. But, in return, it makes TypeScript support in WebStorm more customizable and consistent with other features it provides.

If you decide to use WebStorm as your TypeScript IDE, please make sure the version of supported TypeScript matches what you expect (usually the latest version).

Getting your hands on the workflow

After setting up your editor, we are ready to move to a workflow that you might use to practice throughout this book. It can also be used as the workflow for small TypeScript projects in your daily work.

In this workflow, we'll walk through these topics:

  • What is a tsconfig.json file, and how can you configure a TypeScript project with it?
  • TypeScript declaration files and the typings command-line tool
  • How to write tests running under Mocha, and how to get coverage information using Istanbul
  • How to test in browsers using Karma

Configuring a TypeScript project

The configurations of a TypeScript project can differ for a variety of reasons. But the goals remain clear: we need the editor as well as the compiler to recognize a project and its source files correctly. And tsconfig.json will do the job.

Introduction to tsconfig.json

A TypeScript project does not have to contain a tsconfig.json file. However, most editors rely on this file to recognize a TypeScript project with specified configurations and to provide related features.

A tsconfig.json file accepts three fields: compilerOptions, files, and exclude. For example, a simple tsconfig.json file could be like the following:

{ 
  "compilerOptions": { 
    "target": "es5", 
    "module": "commonjs", 
    "rootDir": "src", 
    "outDir": "out" 
  }, 
  "exclude": [ 
    "out", 
    "node_modules" 
  ] 
} 

Or, if you prefer to manage the source files manually, it could be like this:

{ 
  "compilerOptions": { 
    "target": "es5", 
    "module": "commonjs", 
    "rootDir": "src", 
    "outDir": "out" 
  }, 
  "files": [ 
    "src/foo.ts", 
    "src/bar.ts" 
  ] 
} 

Previously, when we used tsc, we needed to specify the source files explicitly. Now, with tsconfig.json, we can directly run tsc without arguments (or with -w/--watch if you want incremental compilation) in a folder that contains tsconfig.json.

Compiler options

As TypeScript is still evolving, its compiler options keep changing, with new features and updates. An invalid option may break the compilation or editor features for TypeScript. When reading these options, keep in mind that some of them might have been changed.

The following options are useful ones out of the list.

target

target specifies the expected version of JavaScript outputs. It could be es5 (ECMAScript 5), es6 (ECMAScript 6/2015), and so on.

Features (especially ECMAScript polyfills) that are available in different compilation targets vary. For example, before TypeScript 2.1, features such as async/await were available only when targeting ES6.

The good news is that Node.js 6 with the latest V8 engine has supported most ES6 features. And the latest browsers have also great ES6 support. So if you are developing a Node.js application or a browser application that's not required for backward compatibilities, you can have your configuration target ES6.

module

Before ES6, JavaScript had no standard module system. Varieties of module loaders are developed for different scenarios, such as commonjs, amd, umd, system, and so on.

If you are developing a Node.js application or an npm package, commonjs could be the value of this option. Actually, with the help of modern packaging tools such as webpack and browserify, commonjs could also be a nice choice for browser projects as well.

declaration

Enable this option to generate .d.ts declaration files along with JavaScript outputs. Declaration files could be useful as the type information source of a distributed library/framework; it could also be helpful for splitting a larger project to improve compiling performance and division cooperation.

sourceMap

By enabling this option, TypeScript compiler will emit source maps along with compiled JavaScript.

jsx

TypeScript provides built-in support for React JSX (.tsx) files. By specifying this option with value react, TypeScript compiler will compile .tsx files to plain JavaScript files. Or with value preserve, it will output .jsx files so you can post-process these files with other JSX compilers.

noEmitOnError

By default, TypeScript will emit outputs no matter whether type errors are found or not. If this is not what you want, you may set this option to true.

noEmitHelpers

When compiling a newer ECMAScript feature to a lower target version of JavaScript, TypeScript compiler will sometimes generate helper functions such as __extends (ES6 to lower versions), and __awaiter (ES7 to lower versions).

Due to certain reasons, you may want to write your own helper functions, and prevent TypeScript compiler from emitting these helpers.

noImplicitAny

As TypeScript is a superset of JavaScript, it allows variables and parameters to have no type notation. However, it could help to make sure everything is typed.

By enabling this option, TypeScript compiler will give errors if the type of a variable/parameter is not specified and cannot be inferred by its context.

experimentalDecorators*

As decorators, at the time of writing this book, has not yet reached a stable stage of the new ECMAScript standard, you need to enable this option to use decorators.

emitDecoratorMetadata*

Runtime type information could sometimes be useful, but TypeScript does not yet support reflection (maybe it never will). Luckily, we get decorator metadata that will help under certain scenarios.

By enabling this option, TypeScript will emit decorators along with a Reflect.metadata() decorator which contains the type information of the decorated target.

outDir

Usually, we do not want compiled files to be in the same folder of source code. By specifying outDir, you can tell the compiler where you would want the compiled JavaScript files to be.

outFile

For small browser projects, we might want to have all the outputs concatenated as a single file. By enabling this option, we can achieve that without extra build tools.

rootDir

The rootDir option is to specify the root of the source code. If omitted, the compiler would use the longest common path of source files. This might take seconds to understand.

For example, if we have two source files, src/foo.ts and src/bar.ts, and a tsconfig.json file in the same directory of the src folder, the TypeScript compiler will use src as the rootDir, so when emitting files to the outDir (let's say out), they will be out/foo.js and out/bar.js.

However, if we add another source file test/test.ts and compile again, we'll get those outputs located in out/src/foo.js, out/src/bar.js, and out/test/test.js respectively. When calculating the longest common path, declaration files are not involved as they have no output.

Usually, we don't need to specify rootDir, but it would be safer to have it configured.

preserveConstEnums

Enum is a useful tool provided by TypeScript. When compiled, it's in the form of an Enum.member expression. Constant enum, on the other hand, emits number literals directly, which means the Enum object is no longer necessary.

And thus TypeScript, by default, will remove the definitions of constant enums in the compiled JavaScript files.

By enabling this option, you can force the compiler to keep these definitions anyway.

strictNullChecks

TypeScript 2.1 makes it possible to explicitly declare a type with undefined or null as its subtype. And the compiler can now perform more thorough type checking for empty values if this option is enabled.

stripInternal*

When emitting declaration files, there could be something you'll need to use internally but without a better way to specify the accessibility. By commenting this code with /** @internal */ (JSDoc annotation), TypeScript compiler then won't emit them to declaration files.

isolatedModules

By enabling this option, the compiler will unconditionally emit imports for unresolved files.

Note

Options suffixed with * are experimental and might have already been removed when you are reading this book. For a more complete and up-to-date compiler options list, please check out http://www.typescriptlang.org/docs/handbook/compiler-options.html.

Adding source map support

Source maps can help a lot while debugging, no matter for a debugger or for error stack traces from a log.

To have source map support, we need to enable the sourceMap compiler option in tsconfig.json. Extra configurations might be necessary to make your debugger work with source maps.

For error stack traces, we can use the help of the source-map-support package:

$ npm install source-map-support --save

To put it into effect, you can import this package with its register submodule in your entry file:

import 'source-map-support/register'; 

Downloading declarations using typings

JavaScript has a large and booming ecosystem. As the bridge connecting TypeScript and other JavaScript libraries and frameworks, declaration files are playing a very important role.

With the help of declaration files, TypeScript developer can use existing JavaScript libraries with nearly the same experience as libraries written in TypeScript.

Thanks to the efforts of the TypeScript community, almost every popular JavaScript library or framework got its declaration files on a project called DefinitelyTyped. And there has already been a tool called tsd for declaration file management. But soon, people realized the limitation of a single huge repository for everything, as well as the issues tsd cannot solve nicely. Then typings is gently becoming the new tool for TypeScript declaration file management.

Installing typings

typings is just another Node.js package with a command-line interface like TypeScript compiler. To install typings, simply execute the following:

$ npm install typings -g

To make sure it has been installed correctly, you can now try the typings command with argument --version:

$ typings --version
1.x.x

Downloading declaration files

Create a basic Node.js project with a proper tsconfig.json (module option set as commonjs), and a test.ts file:

import * as express from 'express'; 

Without the necessary declaration files, the compiler would complain with Cannot find module express. And, actually, you can't even use Node.js APIs such as process.exit() or require Node.js modules, because TypeScript itself just does not know what Node.js is.

To begin with, we'll need to install declaration files of Node.js and Express:

$ typings install env~node --global
$ typings install express

If everything goes fine, typings should've downloaded several declaration files and saved them to folder typings, including node.d.ts, express.d.ts, and so on. And I guess you've already noticed the dependency relationship existing on declaration files.

Note

If this is not working for you and typings complains with Unable to find "express" ("npm") in the registry then you might need to do it the hard way - to manually install Express declaration files and their dependencies using the following command: $ typings install dt~<package-name> --global

The reason for that is the community might still be moving from DefinitelyTyped to the typings registry. The prefix dt~ tells typings to download declaration files from DefintelyTyped, and --global option tells typings to save these declaration files as ambient modules (namely declarations with module name specified).

typings has several registries, and the default one is called npm (please understand this npm registry is not the npm package registry). So, if no registry is specified with <source>~ prefix or --source option, it will try to find declaration files from its npm registry. This means that typings install express is equivalent to typings install npm~express or typings install express --source npm.

While declaration files for npm packages are usually available on the npm registry, declaration files for the environment are usually available on the env. registry. As those declarations are usually global, a --global option is required for them to install correctly.

Option "save"

typings actually provides a --save option for saving the typing names and file sources to typings.json. However, in my opinion, this option is not practically useful.

It's great to have the most popular JavaScript libraries and frameworks typed, but these declaration files, especially declarations not frequently used, can be inaccurate, which means there's a fair chance that you will need to edit these files yourself.

It would be nice to contribute declarations, but it would also be more flexible to have typings m  managed by source control as part of the project code.

Testing with Mocha and Istanbul

Testing could be an important part of a project, which ensures feature consistency and discovers bugs earlier. It is common that a change made for one feature could break another working part of the project. A robust design could minimize the chance but we still need tests to make sure.

It could lead to an endless discussion about how tests should be written and there are interesting code design techniques such as test-driven development (TDD); though there has been a lot of debates around it, it still worth knowing and may inspire you in certain ways.

Mocha and Chai

Mocha has been one of the most popular test frameworks for JavaScript, while Chaiis a good choice as an assertion library. To make life easier, you may write tests for your own implementations of contents through this book using Mocha and Chai.

To install Mocha, simply run the following command, and it will add mocha as a global command-line tool just like tsc and typings:

$ npm install mocha -g

Chai, on the other hand, is used as a module of a project, and should be installed under the project folder as a development dependency:

$ npm install chai --save-dev

Chai supports should style assertion. By invoking chai.should(), it adds the should property to the prototype of Object, which means you can then write assertions such as the following:

'foo'.should.not.equal('bar'); 
'typescript'.should.have.length(10); 

Writing tests in JavaScript

By executing the command mocha, it will automatically run tests inside the test folder. Before we start to write tests in TypeScript, let's try it out in plain JavaScript and make sure it's working.

Create a file test/starter.js and save it with the following code:

require('chai').should(); 
 
describe('some feature', () => {  
  it('should pass', () => { 
    'foo'.should.not.equal('bar'); 
  }); 
 
  it('should error', () => { 
    (() => { 
      throw new Error(); 
    }).should.throw(); 
  }); 
}); 

Run mocha under the project folder and you should see all tests passing.

Writing tests in TypeScript

Tests written in TypeScript have to be compiled before being run; where to put those files could be a tricky question to answer.

Some people might want to separate tests with their own tsconfig.json:

src/tsconfig.json 
test/tsconfig.json 

They may also want to put output files somewhere reasonable:

out/app/ 
out/test/ 

However, this will increase the cost of build process management for small projects. So, if you do not mind having src in the paths of your compiled files, you can have only one tsconfig.json to get the job done:

src/ 
test/ 
tsconfig.json 

The destinations will be as follows:

out/src/ 
out/test/ 

Another option I personally prefer is to have tests inside of src/test, and use the test folder under the project root for Mocha configurations:

src/ 
src/test/ 
tsconfig.json 

The destinations will be as follows:

out/ 
out/test/ 

But, either way, we'll need to configure Mocha properly to do the following:

  • Run tests under the out/test directory
  • Configure the assertion library and other tools before starting to run tests

To achieve these, we can take advantage of the mocha.opts file instead of specifying command-line arguments every time. Mocha will combine lines in the mocha.opts file with other command-line arguments given while being loaded.

Create test/mocha.opts with the following lines:

--require ./test/mocha.js 
out/test/ 

As you might have guessed, the first line is to tell Mocha to require ./test/mocha.js before starting to run actual tests. And the second line tells Mocha where these tests are located.

And, of course, we'll need to create test/mocha.js correspondingly:

require('chai').should(); 

Almost ready to write tests in TypeScript! But TypeScript compiler does not know how would function describe or it be like, so we need to download declaration files for Mocha:

$ typings install env~mocha --global

Now we can migrate the test/starter.js file to src/test/starter.ts with nearly no change, but removing the first line that enables the should style assertion of Chai, as we have already put it into test/mocha.js.

Compile and run; buy me a cup of coffee if it works. But it probably won't. We've talked about how TypeScript compiler determines the root of source files when explaining the rootDir compiler option. As we don't have any TypeScript files under the src folder (not including its subfolders), TypeScript compiler uses src/test as the rootDir. Thus the compiled test files are now under the out folder instead of the expected out/test.

To fix this, either explicitly specify rootDir, or just add the first non-test TypeScript file to the src folder.

Getting coverage information with Istanbul

Coverage could be important for measuring the quality of tests. However, it might take much effort to reach a number close to 100%, which could be a burden for developers. To balance efforts on tests and code that bring direct value to the product, there would go another debate.

Install Istanbul via npm just as with the other tools:

$ npm install istanbul -g

The subcommand for Istanbul to generate code coverage information is istanbul cover. It should be followed by a JavaScript file, but we need to make it work with Mocha, which is a command-line tool. Luckily, the entry of the Mocha command is, of course, a JavaScript file.

To make them work together, we'll need to install a local (instead of global) version of Mocha for the project:

$ npm install mocha --save-dev

After installation, we'll get the file _mocha under node_modules/mocha/bin, which is the JavaScript entry we were looking for. So now we can make Istanbul work:

$ istanbul cover node_modules/mocha/bin/_mocha

Then you should've got a folder named coverage, and within it the coverage report.

Reviewing the coverage report is important; it can help you decide whether you need to add tests for specific features and code branches.

Testing in real browsers with Karma

We've talked about testing with Mocha and Istanbul for Node.js applications. It is an important topic for testing code that runs in a browser as well.

Karma is a test runner for JavaScript that makes testing in real browsers on real devices much easier. It officially supports the Mocha, Jasmine, and JUnit testing frameworks, but it's also possible for Karma to work with any framework via a simple adapter.

Creating a browser project

A TypeScript application that runs in browsers can be quite different from a Node.js one. But if you know what the project should look like after the build, you should already have clues on how to configure that project.

To avoid introducing too many concepts and technologies not directly related, I will keep things as simple as possible:

  • We're not going to use module loaders such as Require.js
  • We're not going to touch the code packaging process

This means we'll go with separated output files that need to be put into an HTML file with a script tag manually. Here's the tsconfig.json we'll be playing with; notice that we no longer have the module option, set:

{ 
  "compilerOptions": { 
    "target": "es5", 
    "rootDir": "src", 
    "outDir": "out" 
  }, 
  "exclude": [ 
    "out", 
    "node_modules" 
  ] 
} 

Then let's create package.json and install packages mocha and chai with their declarations:

$ npm init
$ npm install mocha chai --save-dev
$ typings install env~mocha --global
$ typings install chai

And to begin with, let's fill this project with some source code and tests.

Create src/index.ts with the following code:

function getLength(str: string): number { 
  return str.length; 
} 

And create src/test/test.ts with some tests:

describe('get length', () => {  
  it('"abc" should have length 3', () => { 
    getLength('abc').should.equal(3); 
  }); 
 
  it('"" should have length 0', () => { 
    getLength('').should.equal(0); 
  }); 
}); 

Again, in order to make the should style assertion work, we'll need to call chai.should() before tests start. To do so, create file test/mocha.js just like we did in the Node.js project, though the code line slightly differs, as we no longer use modules:

chai.should(); 

Now compile these files with tsc, and we've got our project ready.

Installing Karma

Karma itself runs on Node.js, and is available as an npm package just like other Node.js tools we've been using. To install Karma, simply execute the npm install command in the project directory:

$ npm install karma --save-dev

And, in our case, we are going to have Karma working with Mocha, Chai, and the browser Chrome, so we'll need to install related plugins:

$ npm install karma-mocha karma-chai karma-chrome-launcher --save-dev

Before we configure Karma, it is recommended to have karma-cli installed globally so that we can execute the karma command from the console directly:

$ npm install karma-cli -g

Configuring and starting Karma

The configurations are to tell Karma about the testing frameworks and browsers you are going to use, as well as other related information such as source files and tests to run.

To create a Karma configuration file, execute karma init and answer its questions:

  • Testing framework: Mocha
  • Require.js: no
  • Browsers: Chrome (add more if you like; be sure to install the corresponding launchers)
  • Source and test files:
    • test/mocha.js (the file enables should style assertion)
    • out/*.js (source files)
    • out/test/*.js (test files)

  • Files to exclude: empty
  • Watch for changes: yes

Now you should see a karma.conf.js file under the project directory; open it with your editor and add 'chai' to the list of option frameworks.

Almost there! Execute the command karma start and, if everything goes fine, you should have specified browsers opened with the testing results being logged in the console in seconds.

Integrating commands with npm

The npm provides a simple but useful way to define custom scripts that can be run with the npm run command. And it has another advantage - when npm run a custom script, it adds node_modules/.bin to the PATH. This makes it easier to manage project-related command-line tools.

For example, we've talked about Mocha and Istanbul. The prerequisite for having them as commands is to have them installed globally, which requires extra steps other than npm install. Now we can simply save them as development dependencies, and add custom scripts in package.json:

"scripts": { 
  "test": "mocha", 
  "cover": "istanbul cover node_modules/mocha/bin/_mocha" 
}, 
"devDependencies": { 
  "mocha": "latest", 
  "istanbul": "latest" 
} 

Now you can run test with npm run test (or simply npm test), and run cover with npm run cover without installing these packages globally.

Why not other fancy build tools?

You might be wondering: why don't we use a build system such as Gulp to set up our workflow? Actually, when I started to write this chapter, I did list Gulp as the tool we were going to use. Later, I realized it does not make much sense to use Gulp to build the implementations in most of the chapters in this book.

There is a message I want to deliver: balance.

Once, I had a discussion on balance versus principles with my boss. The disagreement was clear: he insisted on controllable principles over subjective balance, while I prefer contextual balance over fixed principles.

Actually, I agree with him, from the point of view of a team leader. A team is usually built up with developers at different levels; principles make it easier for a team to build high-quality products, while not everyone is able to find the right balance point.

However, when the role turns from a productive team member to a learner, it is important to learn and to feel the right balance point. And that's called experience.

Summary

The goal of this chapter was to introduce a basic workflow that could be used by the reader to implement the design patterns we'll be discussing.

We talked about the installation of TypeScript compiler that runs on Node.js, and had brief introductions to popular TypeScript editors and IDEs. Later, we spent quite a lot of pages walking through the tools and frameworks that could be used if the reader wants to have some practice with implementations of the patterns in this book.

With the help of these tools and frameworks, we've built a minimum workflow that includes creating, building, and testing a project. And talking about workflows, you must have noticed that they slightly differ among applications for different runtimes.

In the next chapter, we'll talk about what may go wrong and mess up the entire project when its complexity keeps growing. And we'll try to come up with specific patterns that can solve the problems this very project faces.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • This step-by-step guide will would demonstrate all the important design patterns in practice
  • This book is the only documentation on the market focusing on design patterns in TypeScript
  • This book is packed with rich examples that will improve your efficiency and encourage code reuse

Description

In programming, there are several problems that occur frequently. To solve these problems, there are various repeatable solutions that are known as design patterns. Design patterns are a great way to improve the efficiency of your programs and improve your productivity. This book is a collection of the most important patterns you need to improve your applications’ performance and your productivity. The journey starts by explaining the current challenges when designing and developing an application and how you can solve these challenges by applying the correct design pattern and best practices. Each pattern is accompanied with rich examples that demonstrate the power of patterns for a range of tasks, from building an application to code testing. We’ll introduce low-level programming concepts to help you write TypeScript code, as well as work with software architecture, best practices, and design aspects.

Who is this book for?

If you are a TypeScript developer, this book is for you. No knowledge of design patterns is required to read this book.

What you will learn

  • Understand the challenges and implications of developing an enterprise application
  • Install and configure the necessary tools in order to start developing an application
  • Identify the challenges when developing an application
  • Apply GoF patterns in an application with a testing approach
  • Use and utilize design patterns while developing a TypeScript application or during JavaScript application development
  • Reference to SOLID principles and what their benefits do to your projects
  • Apply various principles in a TypeScript application
  • Improve code quality and development speed
Estimated delivery fee Deliver to Canada

Economy delivery 10 - 13 business days

Can$24.95

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Aug 29, 2016
Length: 256 pages
Edition : 1st
Language : English
ISBN-13 : 9781785280832
Vendor :
Microsoft
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Canada

Economy delivery 10 - 13 business days

Can$24.95

Product Details

Publication date : Aug 29, 2016
Length: 256 pages
Edition : 1st
Language : English
ISBN-13 : 9781785280832
Vendor :
Microsoft
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just Can$6 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just Can$6 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total Can$ 195.97
TypeScript Design Patterns
Can$55.99
TypeScript Blueprints
Can$69.99
Node.js  Design Patterns
Can$69.99
Total Can$ 195.97 Stars icon

Table of Contents

9 Chapters
1. Tools and Frameworks Chevron down icon Chevron up icon
2. The Challenge of Increasing Complexity Chevron down icon Chevron up icon
3. Creational Design Patterns Chevron down icon Chevron up icon
4. Structural Design Patterns Chevron down icon Chevron up icon
5. Behavioral Design Patterns Chevron down icon Chevron up icon
6. Behavioral Design Patterns: Continuous Chevron down icon Chevron up icon
7. Patterns and Architectures in JavaScript and TypeScript Chevron down icon Chevron up icon
8. SOLID Principles Chevron down icon Chevron up icon
9. The Road to Enterprise Application Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.7
(3 Ratings)
5 star 66.7%
4 star 0%
3 star 0%
2 star 0%
1 star 33.3%
Amazon Customer Oct 10, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book is not only about how design patterns could be used in TypeScript, but also lots of best practice in TS introduced by the author. The Design Pattern itself is important, but why we need it and how to use it is much more important, which has also been introduced in this book
Amazon Verified review Amazon
S S. Sep 13, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Post for my friend WanderWang[1]: This book introduces the best practices of TypeScript development workflow at the beginning of the book. Next, combined with the TypeScript's own syntax characteristics, introduced a lot of design patterns in the TypeScript implementation, I found a lot of examples are from the actual project will be encountered problems and solutions. This book can guide me how to write high-quality TypeScript code, the author did a good work![1] [...]
Amazon Verified review Amazon
Archimedes Oct 23, 2016
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
"Thanks to the efforts of the TypeScript community, almost every popular JavaScript library got its declaration files on a project called DefinitelyTyped. And there has already been a tool called tsd for declaration file management. But soon, people realized the limitation of a single huge repository for everything, as well as the issues tsd cannot solve nicely.""Compile and run; buy me a cup of coffee it it works. But it probably won't."This is just a fraction of the nonsensical English that takes place in chapter one. Clearly English is the author's second language, and the mere fact that he can write a book in a language other than his primary language is really quite astonishing. HOWEVER, I don't like to read broken English and what is clear from page 1 is that this book has not been edited by someone whose first language is English. I would expect that from a book that is nearly $30. I really would have liked to have read the subsequent chapters illustrating GoF design patterns implemented with TypeScript. I just couldn't make it out of chapter 1.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela