Thursday, December 3, 2015

Book Review: Learning TypeScript

Packt Publishing recently published Remo H. Jansen's Learning TypeScript with the subtitle, "Exploit the features of TypeScript to develop and maintain captivating web applications with ease." The book features well over 300 pages that constitute ten chapters and a preface.

Preface

The Preface of Learning TypeScript begins with an introduction to the current state of JavaScript and an explanation of why Microsoft developed TypeScript. The Preface provides short descriptions of what each of its ten chapters entails and states that Learning TypeScript "teach[es] TypeScript's core features" and "also explores the power of some tools, design principles, best practices and ... demonstrates how to apply them in a real-life application."

The "What you need for this book" section of the Preface states that TypeScript 1.5 is used for the book's examples and that the Atom text editor is used in the book (though any text editor should be fine).

The "Who this book is for" section of the Preface explains that Learning TypeScript is for an "intermediate-level JavaScript developer aiming to learn TypeScript to build beautiful web applications" who has "no prior knowledge of TypeScript," but does have "a basic understanding of jQuery."

Chapter 1: Introducing TypeScript

The first sentence of the initial chapter of Learning TypeScript states in that single sentence the intent of the book: "This book focuses on TypeScript's object-oriented nature and how it can help you to write better code." The chapter then opens with a discussion of the TypeScript architecture and TypeScript design goals. The discussed design goals include static typing, compatibility with JavaScript, code structuring mechanisms, avoidance of runtime overhead for "emitted" JavaScript code, and ability to execute on multiple platforms.

In the discussion of the TypeScript architecture, the book includes a copy of the diagram available in the Microsoft TypeScript Architectural Overview Wiki page and then provides a brief explanation for each layer in that architecture diagram.

Learning TypeScript advises the reader to use the TypeScript Playground as an easy way to play with and try out TypeScript code. A screen snapshot and explanatory text describe how a developer can type in TypeScript code on the left and see the corresponding JavaScript code on the right. This section of the first chapter also describes using the TypeScript compiler built into VisualStudio or downloaded separately via node.js's npm.

Chapter 1 of Learning TypeScript moves from its discussion of accessing the TypeScript compiler to introducing TypeScript types. This section introduces TypeScript's optional static type notation along with the variable declaration keywords var, let, and const. Union types, type guards, and type aliases are also introduced in this introductory chapter.

A good explanation of ambient declarations is presented and is followed by tables listing arithmetic operators, comparison operators, logical operators, bitwise operators, and assignment operators in TypeScript. The section on flow-control statements (if, if/else, switch, while, do/while, for, and for...in) briefly describes each and illustrates each with small code listings.

Chapter 1's survey of basic TypeScript language features wraps up with introductions to TypeScript's functions, classes, interfaces, and namespaces. The chapter concludes with an example that applies many of these language features.

Chapter 2: Automating Your Development Workflow

The second chapter of Learning TypeScript covers "some tools to automate our development workflow ... to reduce the amount of time that we usually spend on simple and repetitive tasks." The chapter begins by delineating tools to install for the development environment. These tools include Node.js, the Atom text editor and atom-typescript package, git and github, node package manager npm, Bower, DefinitelyTyped, Gulp, gulp-tslint, CommonJS, Karma, BrowserSync, and Travis CI.

Over ten years ago, Ruby on Rails introduced me to the power and convenience of scaffolding. "Scaffolding" is defined in Learning TypeScript as a tool "used to autogenerate the project structure, build scripts, and much more." The chapter states that "the most popular scaffolding tool these days is Yeoman" and then demonstrates applying Yeoman to generate a beginning source directory structure.

Chapter 3: Working with Functions

Chapter 3 of Learning TypeScript is dedicated to functions because "functions are the fundamental building block of any application in TypeScript." The chapter begins with some introductory information on TypeScript functions, how to declare them, and how to overload them. During its introduction to functions, Chapter 3 also explains the use of template strings (back tick characters) and placeholders (${}). The chapter also highlights some of the differences between TypeScript functions and JavaScript functions. For example, it explains, "Unlike JavaScript, the TypeScript compiler will throw an error if we attempt to invoke a function without providing the exact number and type of parameters that its signature declares" (unless, as the chapter explains, you indicate one or more parameters are optional using ? syntax, a default value, or rest parameters).

Chapter 3 also explains that TypeScript scope, like JavaScript scope, is function-based. Indeed, the author points out that "a TypeScript application is a JavaScript application at runtime" and that JavaScript’s variable hoisting is in force in TypeScript. Examples are provided of using let and const in TypeScript to explicitly specify different block scopes than the default function scope.

Immediately invoked function expression (IIFE) is introduced in the third chapter as a pattern "to avoid variable hoisting from within blocks" and "to prevent us from polluting the global scope." Chapter 3 also introduces generic function in TypeScript. The chapter looks at tag templates as well and notes that this is a feature anticipated for TypeScript 1.6.

The final major section of Chapter 3 is "Asynchronous programming in TypeScript." This section covers callback functions, higher-order functions, and arrow functions (fat arrow functions). The section also provides an example of "callback hell" related to loading a Handlebars template and then discusses use of Promises (and provides an example based on Q's implementation of Promise) to dress these callback issues.

The section of Learning TypeScript's third chapter on asynchronous programming looks at anticipated asynchronous functions in TypeScript and refers the reader to the TypeScript Roadmap for details on when this feature will be available (looks like TypeScript 2.0 at time of this writing). The chapter also covers generator functions (expected in TypeScript 1.6).

4. Object-Oriented Programming with TypeScript

Learning TypeScript's fifth chapter begins with a review of the SOLID principles of object-oriented programming and then begins to describe "how to write TypeScript code that adheres to these principles so that our applications are easy to maintain and extend over time." The chapter revisits classes, constructors, and interfaces in the context of the SOLID principles. It also introduces the object-oriented concepts of association, aggregation, composition, inheritance, mixins, generic classes, and generic constraints.

Chapter 4 of Learning TypeScript introduces TypeScript modules and contrasts them with namespaces. This section describes, compares, and contrasts TypeScript's "available module definition syntaxes": ES6 module (TypeScript 1.5), external modules (pre-TypeScript 1.6), AMD and require.js modules, CommonJS modules, UMD modules, and SystemJS modules.

The fourth chapter concludes with a discussion on circular dependencies and illustrates use of Atom's generation of a dependency tree graph to help identify circular dependencies.

Chapter 5: Runtime

Chapter 5 of Learning TypeScript opens with the reminder that "TypeScript runtime is the JavaScript runtime" and adds, "TypeScript is only used at design time; the TypeScript code is then compiled into JavaScript and finally executed. The JavaScript runtime is in charge of the execution. Is important to understand that we never execute TypeScript code and we always execute JavaScript code." For someone familiar with the JavaScript runtime who is reading Learning TypeScript to, well, learn TypeScript, this chapter may not be necessary.

The fifth chapter points out the importance of being aware of the environment to which a TypeScript (or JavaScript) application is being deployed as different variables and objects are available or not available in different types of environments. The chapter introduces JavaScript runtime concepts of heap, queue, stack, and frames and displays a simple color graphic of these concepts seemingly adapted from the image on the Concurrency model and Event Loop page of the Mozilla Developer Network. There is also brief discussion of how the JavaScript event loop works.

Chapter 5 discusses one of the nuances of JavaScript that I have found to be most challenging: its behavior depends on the context in which this is used and whether it's in strict mode or non-strict mode. There is brief discussion of using this in the global context and more extensive discussion of using this in the function context with emphasis on invoking the call, apply, and bind methods on the Function.prototype object.

Learning TypeScript's fifth chapter concludes with fairly detailed introductions to JavaScript Prototypes and JavaScript closures.

Chapter 6: Application Performance

Learning TypeScript's sixth chapter begins with summary of several types of resources that might have limited availability. The chapter then briefly describes several performance metrics before covering different types of performance analysis. It introduces the Resource Timing API, presents an image similar to that on the W3C Resource Timing specification page and very much like the image on the performance-bookmarklet project page, and demonstrates using the Performance-Bookmarklet browser extension.

The sixth chapter's discussion on "network performance and user experience" makes some interesting points based on a 2009 Akamai study and shows an interesting image that can also be seen in the NewRelic article Velocity Roundup: Real-Users, Performance and What Matters to You. The chapter also introduces and demonstrates using Google's PageSpeed Insights and YSlow to measure page loading times and offer suggestions for faster user experience.

Chapter 6's section on "GPU performance analysis" applies stats.js in an example demonstrating measuring of frames per second and the section on "CPU performance analysis" demonstrates using the Chrome Developer Tools Profiler. Google Chrome Developer tools are also used in this chapter's demonstration of tracking down JavaScript memory leaks.

Another section of Chapter 6 describes the JavaScript garbage collector and provides recommendations for achieving the best performance related to garbage collection. The "Performance optimization automation" section discusses automating performance monitoring and performance testing.

The concluding section of Chapter 6 covers exception handling in TypeScript and introduces the Error class, a pre-TypeScript 1.6 approach to extend the Error class for a custom error, and use of try, catch, and finally. Like Chapter 5, Chapter 6 is, for the most part, not specific to TypeScript but rather applies to JavaScript in general and also applies to TypeScript.

Chapter 7: Application Testing

The focus of Learning TypeScript's seventh chapter is "how to write unit tests for TypeScript applications." This chapter begins with a review of key terms related to unit testing such as assertion, spec, test case, test suite, test doubles (spy, dummy, stub, and mock) and test coverage.

The examples in Chapter 7 make use of a wide variety of tools and these are each briefly described in the chapter (including how to install, typically via npm install). The covered tools include Gulp for running tasks used by tests, Karma for executing tests, Istanbul for test coverage, Mocha for the test framework, Chai and Karma-Chai for test assertions, and Sinon for test doubles (test isolation) support, tsd to manage third-party tool dependencies, PhantomJS and karma-phantomjs-launcher for browser testing without starting a browser, and Selenium and Nightwatch.js for end-to-end testing.

Chapter 7's discussion of "testing planning and methodologies" briefly describes test-driven development (TDD) and behavior-driven development (BDD). There are also brief descriptions of different types of tests ranging from unit tests to end-to-end tests. The chapter concludes with explanations and discussion illustrating application of the tools to test TypeScript applications.

Chapter 8: Decorators

Chapter 7 of Learning TypeScript covers annotations and decorators. The chapter begins by explaining that decorators are planned for ECMAScript 7, but are available now in TypeScript 1.5. There is explanation regarding annotations (originated with AtScript, which is now part of TypeScript) and decorators and their subtle differences.

The seventh chapter of Learning TypeScript explains and illustrates decorators (including how to implement them) for classes, properties, methods, and parameters. The section on decorators also explains why and how a decorator factory is used and how to use a decorator with arguments.

Chapter 7 concludes with an introduction to the Reflection Metadata API. The ability to use Reflect.getMetadata is planned for ES7, but is available already in TypeScript 1.5.

Chapter 9: Application Architecture

Chapter 9 of Learning TypeScript contains discussion on application archictecture considerations for TypeScript applications. It covers the increasingly ubiquitous Single-Page Application architecture and discusses application of Ajax with Handlebars.js and jQuery.

Chapter 9's section on "MV* architecture" introduces "the Model-View-Controller (MVC) design pattern and some of its derivative versions, such as Model-View-ViewModel (MVVM) and Model-View-Presenter (MVP)." There are some useful diagrams in this section illustrating these concepts and versions of these diagrams are available in the presentations Working with AngularJS and About Flux.

After its introductory coverage of single-page applications and so-called MV* architectures, the ninth chapter looks at how to go about selecting a framework to use with single-page applications rather than writing one from scratch. This section provides a useful graphic that depicts different potentially desired characteristics of such a framework with one or more frameworks that meets satisfies those desires. I also appreciated this section's reference to TodoMVC for "helping you select an MV* framework."

Learning TypeScript's ninth chapter concludes with a sizable section on developing a custom MV* framework. There are several code listings and associated explanation associated with this example that the author warns is for learning purposes rather than for production use.

Chapter 10: Putting Everything Together

Learning TypeScript's final chapter "[puts] into practice the majority of the concepts ... covered in the previous chapters" via an example demonstrating development of a "a small single-page web application using the SPA framework" that was introduced in Chapter 9. The chapter contains several code listings and explanations of each part of the application. The chapter briefly covers unit testing of the application and preparing the application for a production release.

General Observations

  • The book that is the subject of this review, Learning TypeScript, should not be confused with Bryan Rayner's presentation Learning TypeScript: Or, An Appeal to Embrace Typed Languages.
  • Some chapters of Learning TypeScript are TypeScript-specific and others are more ECMAScript/JavaScript-general. Because TypeScript is a superset of JavaScript and an implementation of ECMAScript, this is a sensible approach for a book with a title that includes "TypeScript".
    • Developers with no TypeScript or JavaScript experience can use Learning TypeScript as a completely self-contained book to introduce themselves to TypeScript and the JavaScript ecosystem works in.
    • Developers who already have TypeScript experience may still find the book useful because of the details provided related to ECMAScript in general (particularly newer and future features).
    • Even developers who are not interested in TypeScript in particular, but who are interested in modern and future ECMAScript features, may find several of the chapters to be useful.
      • For example, while the chapter of Learning TypeScript on object-oriented concepts will not bring many new concepts to the attention of Java, C++, and C# developers, it could be very useful for a JavaScript developer with minimal class-based object-oriented experience who wants to learn more about where ECMAScript's class support is heading.
      • TypeScript already implements several proposed new ECMAScript features, so learning about TypeScript can often translate to better understanding JavaScript's future.
      • TypeScript has been adopted by Angular 2, making understanding of it important to many web developers who might not otherwise be interested in TypeScript.
  • There are numerous code listings in Learning TypeScript. Most are short and do a good job of illustrating the concepts. Even in the PDF version I reviewed, they are black font on white background with no color syntax and no line numbers. I encourage anyone following along with the code examples to download the source code and open it in their favorite IDE or text editor.
  • It's a minor pet peeve of mine, but I'll point it out here for completeness. Several of the examples in Learning TypeScript use the "legacy" example keywords "foo" and "bar." I was starting to think books were getting away from this, but this is a modern book that still uses those generic names. I've never liked these terms for multiple reasons, but perhaps my strongest reason to dislike them is that they have zero contextual meaning. I'd rather see contrived but still more realistic variable names in examples.
  • The TypeScript Language Specification (1.5 as of this writing), the TypeScript Tutorial, and the TypeScript Handbook are additional very useful resources.

Conclusion

Learning TypeScript provides a solid introduction to TypeScript. It goes beyond that, however, and, via discussion of TypeScript, examines modern ECMAScript and where ECMAScript is going in the near future. The reader of Learning TypeScript not only learns about TypeScript, but learns about recent and soon-to-be-added features for JavaScript. Learning TypeScript contains TypeScript-specific details as well as JavaScript/ECMAScript-general details. This demonstrates how TypeScript can be used in conjunction with other JavaScript tools and frameworks.

No comments: