The TypeScript team recently announced version 3.0 of TypeScript, introducing new techniques for creating and scaling projects, operations on parameter lists, new types to enforce explicit checks, and improvements to the developer user experience in handling errors reported by TypeScript.
TypeScript 3.0 intentionally has very minimal breaking changes from 2.x, with the hope of making it easy for projects to upgrade. The breaking changes to keep in mind when upgrading include:
unknown
was added as a new built-in type. As such, the word "unknown" is now a reserved type name and no longer gets used in type declarations- The internal method
LanguageService#getSourceFile
has been removed after being marked for deprecation two years ago - The function TypeChecker#getSymbolDisplayBuilder and its associated interfaces was removed after an earlier deprecation notice. These should get replaced with emitter and node builder
- The functions escapeIdentifier and unescapeIdentifier have been removed after being marked for deprecation
- The following functions have been changed to internal TypeScript methods and are no longer part of the public API for TypeScript:
TypeChecker#getSuggestionForNonexistentProperty
,TypeChecker#getSuggestionForNonexistentSymbol
, andTypeChecker#getSuggestionForNonexistentModule
The most significant change in TypeScript 3.0 is project references, which strive to reduce the complexity when managing multiple TypeScript dependencies. Project references allow TypeScript configuration files (tsconfig.json) to now reference other configuration files, making it simpler to separate source code trees into smaller projects. TypeScript and its tooling are updated to understand project references and the order in which projects are built and need to be structured.
Key features touted as part of the project references improvement include faster and more incremental building, as well as editing and refactoring across projects. Two new fields are included in tsconfig.json to support project references:
- composite: a boolean specifying that a project may get referenced and built incrementally
- references: an object with a path field that allows TypeScript to know the current project requires building a referenced project before being built
Beyond allowing third-party tooling to leverage TypeScript's incremental build capabilities, TypeScript 3.0 also includes a new --build
flag to perform simple build operations.
Increased control over the output structure of a project is another benefit of the new project references and build tooling. A typical use case presented is source code shared between client-side and server-side applications. Previously this code would be built twice, and now with project references, the shared dependency only needs to be built a single time.
As this is a very new feature, the TypeScript team hopes that other tool authors can easily support project references, and per TypeScript program manager Daniel Rosenwasser, "for project references to feel as seamless as authoring code with a single tsconfig.json." The TypeScript team is actively seeking feedback on how to make project references and builds easier to use.
The TypeScript project adds richer tuple types including trailing optional elements, restructuring elements at the end of the tuple, and empty tuple types. These enhancements helped make it possible to extract and spread parameter lists with tuples.
The benefit is a great reduction in complex overload definitions,a significant pain point in earlier TypeScript releases. An example provided by the TypeScript team shows that a type definition that looked like:
// TODO : 5 overloads should *probably* be enough for anybody?
function call<T1, T2, T3, T4, R>(fn: (param1: T1, param2: T2, param3: T3, param4: T4) => R, param1: T1, param2: T2, param3: T3, param4: T4): R
function call<T1, T2, T3, R>(fn: (param1: T1, param2: T2, param3: T3) => R, param1: T1, param2: T2, param3: T3): R
function call<T1, T2, R>(fn: (param1: T1, param2: T2) => R, param1: T1, param2: T2): R
function call<T1, R>(fn: (param1: T1) => R, param1: T1): R;
function call<R>(fn: () => R, param1: T1): R;
function call(fn: (...args: any[]) => any, ...args: any[]) {
return fn(...args);
}
Can now be reduced to something more concise:
function call(fn: (arg1: number, arg2: string) => string, arg1: number, arg2: string): string
Improvements to the error case user experience include providing additional context on the possible source of errors, as well as refining many more obtuse error messages into explanations that more clearly explain the source of an error.
Users of JSX in React and other virtual DOM implementations also benefit from more improvements to TypeScript's handling of JSX, in particular support for defaultProps.
The unknown
type is an answer to the overuse of the any
type. The challenges with the any
type, according to Rosenwasser:
The any type is the most-capable type in TypeScript – while it encompasses the type of every possible value, it doesn’t force us to do any checking before we try to call, construct, or access properties on these values. It also lets us assign values of type any to values that expect any other type. This is mostly useful, but it can be a bit lax.
In scenarios where developers wants to explain that something can be any value, but some checking must be performed before using it to prevent further issues, they are now encouraged to use the unknown type. Unlike any, an unknown type is assignable to almost nothing else without a type assertion.
TypeScript 3.0 offers several additional refinements and improvements.
Community support for TypeScript and the 3.0 release is growing, with many prominent projects relying on TypeScript including Angular, Dojo, Ionic, Stencil, Deno, and Nest.js. Ionic CEO Max Lynch recently wrote an article on building a company around TypeScript:
I’m completely sold now on using TypeScript for every single frontend project I ever work on and for every project we build at Ionic.
To get started with TypeScript, install it using npm:
npm install -g typescript
Efforts are already underway on TypeScript 3.1, with support coming for BigInt, a stage 3 ECMAScript proposal that is expected to be part of the ES2019 update to JavaScript.
TypeScript is open source software available under the Apache 2 license. Contributions and feedback are encouraged via the TypeScript GitHub project.