TypeScript 2.6 was released on the 31st of October. It is a moderately sized release like many of the other of the more rapid releases from the TypeScript team over the past year. TypeScript 2.6 include a few key and interesting features.

Strict functions

Probably the most interesting 2.6 feature from our perspective is strict functions. Over the past year or so, the TypeScript team has looked at continuing to make progress on the design goal to statically identify constructs that are likely to be errors and strict functions falls into that category. This feature is enabled under the compiler flag of --strictFunctionTypes and is also include with the --strict flag.

TypeScript strict mode has taken several features over recent releases, which would break backwards compatibility, but enforce far more strict interpretation of types and other code constructs. At SitePen, we strive to have all our code be compliant with strict and have found that the incremental additions have been relatively easy to absorb into our code bases. Most of the time, code that previously worked before a strict feature was added wasn’t as bulletproof as we thought, so in almost every case we are finding errors that could potentially cause code to misbehave in unexpected ways.

Unlike other features, which tend to be enhancements to the enforcement of the type system, strict functions actually transcends the type system and enforces strictness on code that is still technically sound, but could be a source of logic errors. We really like seeing that the TypeScript team goes beyond the pure theory to help us write code that works better in real world situations.

I will admit I still struggle with the type theory sometimes, but it is great to have TypeScript looking after us. If you don’t understand what I am about to say, don’t worry. I am not even sure I fully understand it! So the change is that instead of function types being checked bivariantly, function types will be checked contravariently. What this means is that in certain situations, a previous supertype could be assigned to a subtype, which would lead to logic errors in the code. This change errors on those situations. For example:

class Animal {
  type: string;
}

class Dog extends Animal {
  type = 'dog';
  bark() {
    console.log('bark');
  }
}

interface Comparer<T> {
  compare: (a: T, b: T) => number;
}

declare let dogComparer: Comparer<Dog>;

const animalComparer: Comparer<Animal> = dogComparer; // Error with --strictFunctionTypes

While somewhat complicated, what could happen is that because an instance of Dog is assignable to a variable that is a type of Animal, this code would pass, but it is not very likely that the developer would want to take a function or method that needed a more specific generic type and assign that to a function that only expects a less specific type. In all situations we can think of, this checking would help prevent unintentional errors.

Suppressing errors

This was a rather heated debate for a long time in the TypeScript community. Several developers wanting to ignore errors from the TypeScript compiler, but the fear (including myself) of developers just not addressing issues with the code by ???.

The argument on the other hand was that if it is difficult to migrate an existing code base to TypeScript, trying to address all errors at once can become a barrier to adopting TypeScript. The TypeScript team acknowledged this and now allows the comment of // @ts-ignore to be used to suppress an error on the next line of code.

Additional language services features

One of the most powerful features of TypeScript is the information and services it provides integrated development environments (IDEs). TypeScript powers the language engine for Visual Studio Code for both TypeScript and JavaScript. Many of the features of the last several releases provide very powerful tools to VSCode (and any other editors using the language services) and TypeScript 2.6 is not different. Features and enhancements include:

  • Automatic adding of imports
  • Refactoring features, including extracting constants and locals
  • Ability to convert JSDoc to TypeScript
  • Quick fixes for inferring from usage, invoking uncalled decorators, and installing types from @types
  • Supporting code folding via // #regions

As with many of these features, they will be made available in the next release of Visual Studio Code.

Other improvements

This release also has some performance improvements for the internals of TypeScript, specifically improving the behaviour when using the --watch compiler flag as well as addressing over 200 other issues. It is really impressive the cadence of the TypeScript team and how predictable the releases have been. We are looking forward to this continued pace!