String literal types are a lightweight alternative to string enums. With the introduction of the const assertions in TypeScript 3.4, even type guards can be implemented in a DRY manner.
Posts about TypeScript
I've been doing some Cordova plugin development recently and at some point, I've decided to add TypeScript type declarations to make the plugin easier to consume from Ionic (or other TypeScript based) applications.
I have a hard time recommending the book to anyone. Although it mostly focuses on basics, I don't think it's suitable for beginners because of how short the explanations are. For me, its value was mostly in a few random nuggets of knowledge I stumbled upon while reading.
Recently, we discussed the behavior of Promise.finally in our development team. Even after reading the official documentation, we weren't unanimous on what will happen in certain cases. In the end, I wrote a couple of test cases to make sure about it.
In Ionic 4, even for lazy-loaded modal pages the component must be specified using the type. There's nothing wrong with that. Enforcing strong typing is usually a good idea. However, it can potentially cause a circular dependency, especially if you move the code for creating and opening modal pages to a separate service to avoid repeating the same boilerplate code and make testing easier.
RxJS used to encourage monkey patching of operators and helper functions onto the Observable object. However, this has an unfortunate side effect of making the imports available everywhere. Removing an import from one file can inadvertently break code in other files. To alleviate this problem, alternative imports in the form of lettable operators are available since RxJS 5.5.
Ionic Native makes it very convenient to use Cordova plugins from Ionic applications. Although Ionic Native provides an impressive collection of wrappers for many Cordova plugins, there are still Cordova plugins out there without a corresponding plugin. In such cases you will need to either use them directly without a wrapper or write your own wrapper. The latter option is much simpler than you might think.
The biggest advantage of having a formal description for a RESTful API is the ability to programmatically generate client-side code for calling the service. Unfortunately, it turned out that Swagger tooling still leaves much to be desired, at least for generating TypeScript Angular code.
I keep getting impressed by how feature-rich dependency injection in Angular is. This time I needed it to inject the appropriate implementation of a dependency based on runtime information. Of course, the scenario is well supported.
Angular has great support for validating data in forms, both template-driven and and reactive ones, built imperatively with FormGroup. It is also easy to create own custom validators. However, I did not find it obvious, how to use injected dependencies in non-directive validators for reactive forms.
Many Angular 2 and Ionic 2 APIs return RxJS observables. To unit test your code that's consuming them, you will need to create your own observable streams with test data. With this approach I wrote tests for code reacting to user's current geolocation.
Angular makes heavy use of ECMAScript 2015 modules. All components and other Angular objects are modules themselves, therefore the tutorials explain early on, how to import and use them. However, how does one import a third party library which still exports legacy CommonJS or AMD modules?
By default, Ionic 2 produces unminified development builds. To force an optimized production build, you need to add --prod switch to ionic build or ionic run command. Since development build doesn't include Angular AoT (Ahead of Time) compilation, your production build might turn out broken even if development build of the application worked just fine.
In version 2.1 that was released in December 2016, TypeScript finally added support for downlevel transpilation of async and await keywords for ES3 and ES5 targets. To give this new feature a try, I decided to convert the Angular Tour of Heroes tutorial to use async and await.
Having unit tests usually drastically reduces the need for interactive debugging. However, being able to debug unit tests can sometimes prove very useful. Nowadays, any browser includes a fully featured debugger as part of its developer tools, and Karma test runner has a dedicated feature for in-browser debugging. I wrote short instructions on how exactly to use this feature for a project I am working on.
Although, I have now configured my Cordova project to automatically copy distribution files from installed Bower packages and reference them from HTML pages, there's still one final part of Bower-related configuration left: unit tests also require Bower dependencies. I don't want to manually update the configuration of my test runner every time I install an additional Bower package.
I have no reservations about recommending the book to any existing or future TypeScript developer. It can serve as the first book to start learning the language, but can teach you a lot even if you have already been programming in it for a while.