Few Months back 3.8 and 3.9 version released which brought type-only imports/exports, along with ECMAScript features like private fields,
top-level await
in modules, and new export *
syntaxes, improving the performance and scalability.
What’s New? Lets dive in to feature Which are most important to Developer Point of View.
build
mode with --noEmitOnError
Optional Chaining
/** @deprecated */
Supportunknown
on catch
ClausesTypeScript 4.0 now lets you specify the type of catch
clause variables as unknown instead. unknown
is safer than any because it reminds us that we need to perform some sorts of type-checks before operating on our values.
try {
// ...
} catch (e: unknown) {
// Can't access values on unknowns
// error: Object is of type 'unknown'.
console.log(e.toUpperCase());
if (typeof e === "string") {
// We've narrowed 'e' down to the type 'string'.
console.log(e.toUpperCase());
}
}
Inference
from Constructors
TypeScript 4.0 can now use control flow analysis to determine the types of properties in classes when noImplicitAny
is enabled.
class Square {
// Previously both of these were any
area;
// ^ = (property) Square.area: number
sideLength;
// ^ = (property) Square.sideLength: number
constructor(sideLength: number) {
this.sideLength = sideLength;
this.area = sideLength ** 2;
}
}
In cases where not all paths of a constructor
assign to an instance member, the property is considered to potentially be undefined
.
class Square {
sideLength;
// ^ = (property) Square.sideLength: number | undefined
constructor(sideLength: number) {
if (Math.random()) {
this.sideLength = sideLength;
}
}
get area() {
return this.sideLength ** 2;
// error: Object is possibly 'undefined'.
}
}
In cases where you know better (e.g. you have an initialize method of some sort), you’ll still need an explicit type annotation along with a definite assignment assertion (!)
if you’re in strictPropertyInitialization
.
class Square {
// definite assignment assertion
// v
sideLength!: number;
// ^^^^^^^^
// type annotation
constructor(sideLength: number) {
this.initialize(sideLength);
}
initialize(sideLength: number) {
this.sideLength = sideLength;
}
get area() {
return this.sideLength ** 2;
}
}