The TypeScript team announced the release of TypeScript 3.6, including stricter generators, better developer experience around promises, improvements to array spread accuracy, and a new TypeScript Playground.
Before TypeScript 3.6, it was not possible to differentiate whether values were yielded or returned from generators. TypeScript also would assume the type of yield was any.
With the TypeScript 3.6 release, the type now gets accurately checked for yields, and a new type, Generator
, represents generators. The type declarations for Iterator
and IteratorResult
also get a few new type parameters to support the improvements to type checking for generators in TypeScript. Furthermore, the new Generator
type is now also an Iterator
and always has both the return
and throw
methods available.
interface Generator<T = unknown, TReturn = any, TNext = unknown>
extends Iterator<T, TReturn, TNext> {
next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
return(value: TReturn): IteratorResult<T, TReturn>;
throw(e: any): IteratorResult<T, TReturn>;
[Symbol.iterator](): Generator<T, TReturn, TNext>;
}
To differentiate between returned and yielded values, the IteratorResult
type gets converted to a discriminated union type.
The results of this effort, as explained by TypeScript program manager Daniel Rosenwasser:
TypeScript 3.6 can now narrow down values from iterators when dealing with them directly. To correctly represent the types that can be passed into a generator from calls to
next()
, TypeScript 3.6 also infers certain uses ofyield
within the body of a generator function.
TypeScript 3.6 strives to improve developer experience when working with mishandled promises. Common mistakes when working with promises include forgetting to .then()
or await
the results before passing them to another function. Improvements to TypeScript’s error messages now provide better information to developers. For example:
// Argument of type 'Promise<User>' is not assignable to parameter of type 'User'.
// ...
// Did you forget to use 'await'?
TypeScript supports targeting various versions of JavaScript. For pre-ES2015 compilation targets, TypeScript typically emits constructs for for/of
loops and array spreads, but these can be fairly heavyweight for older versions of JavaScript. TypeScript 3.6 now provides a more straightforward default emit only supporting array types, with support for iterating on other types using the --downlevelIteration
flag. With this compilation flag, the transpiled code improves in its accuracy but is much larger.
Instead of using slice()
and built-ins, TypeScript 3.6 adds a new __spreadArrays
helper to accurately support what happens in ECMAScript 2015 in older targets outside of --downlevelIteration
. The __spreadArrays
helper is also available in tslib, a runtime library of TypeScript helpers.
Prior to TypeScript 3.6, the language did not allow get and set accessors for ambient contexts. Accessors were treated as being the same as properties. The ECMAScript class fields proposal may introduce differing behavior, and to support this behavior and provide appropriate errors in subclasses, getters and setters in ambient contexts is now supported in TypeScript 3.6.
declare class Foo {
// Allowed in 3.6+.
get x(): number;
set x(val: number): void;
}
TypeScript 3.7 will leverage this improvement and emit get/set accessors for generated .d.ts
files.
Before TypeScript 3.6, merging classes and functions would error under any circumstances. With TypeScript 3.6, ambient classes and functions can now merge. This merging change allows a callable constructor pattern to easily get expressed while also allowing namespaces to merge with these declarations. In TypeScript 3.7, the .d.ts
files generated from .js
files can capture the callability and constructability of class-like functions.
TypeScript 3.0 added the --build
flag to support referencing other projects during build time, and TypeScript 3.4 introduced the --incremental
flag for saving information from previous compilations to only rebuild certain files. Before TypeScript 3.6, these flags did not work with third-party build tools such as Webpack. TypeScript 3.6 now provides two sets of APIs to operate on project references and incremental program building. As detailed by Rosenwasser:
For creating
--incremental
builds, users can leverage thecreateIncrementalProgram
andcreateIncrementalCompilerHost
APIs. Users can also re-hydrate old program instances from.tsbuildinfo
files generated by this API using the newly exposedreadBuilderProgram
function, which is only meant to be used as for creating new programs (i.e., you can’t modify the returned instance – it’s only meant to be used for theoldProgram
parameter in othercreate*Program
functions). For leveraging project references, a newcreateSolutionBuilder
function has been exposed, which returns an instance of the new typeSolutionBuilder
.
The TypeScript Playground receives a substantial refresh thanks to Artem Tyurin, adding a significant number of improvements to the playground, making it easier to experiment with TypeScript.
Other TypeScript 3.6 improvements include:
- Support for Unicode characters in identifiers when emitting to ES2015 and later targets
import.meta
Support in SystemJS- Semicolon-Aware Code Edits
- Smarter Auto-Imports
TypeScript 3.6 introduces potentially breaking changes, all of which are consequences of using the new features or changes emerging in the ECMAScript standard:
- Class Members Named "constructor" Are Now Constructors
- The global
window
is no longer defined astype Window,
but now astype Window & typeof globalThis
GlobalFetch
gets replaced withWindowOrWorkerGlobalScope
- Some non-standard properties on
Navigator
get removed - The
experimental-webgl
context gets replaced withwebgl
andwebgl2
- JSDoc Comments No Longer Merge
- Keywords Cannot Contain Escape Sequences
The TypeScript team is already working on features for TypeScript 3.7, including leveraging features introduced in TypeScript 3.6 with generated type definitions.
The TypeScript community is also preparing for the second TSConf event on October 11th with TypeScript founder Anders Hejlsberg delivering the keynote.
TypeScript is open source software available under the Apache 2 license. Contributions and feedback are encouraged via the TypeScript GitHub project and should follow the TypeScript contribution guidelines and Microsoft open source code of conduct.