#What’s New In TypeScript 4.6? – CloudSavvy IT

Table of Contents
“What’s New In TypeScript 4.6? – CloudSavvy IT”

TypeScript 4.6 is this year’s first feature release for the statically typed JavaScript superset. It adds several improvements around constructors, compilation, and code analysis. There are also a couple of breaking changes to be aware of before you upgrade.
Control Flow Analysis Improvements
This release brings several enhancements for TypeScript’s control flow analysis capabilities. They better equip TypeScript to more precisely understand how your code operates, leading to narrower type definitions and fewer unexpected errors.
The first change concerns discriminant property unions that have been destructured from objects. It applies to cases where you’re working with union types that consist of multiple objects. Individual objects in the union may have differences in their type definitions but still share some keys.
It’s common to use those shared keys to conditionally inspect the other parts of the data structure. TypeScript used to error when using this workflow with a destructuring assignment. The destructuring syntax created wholly new variables, devoid of the association that linked them as object properties. The compiler now remembers that the values originated from the same object, allowing simpler code to be written.
The release announcement uses an example similar to this:
type Action = | {kind: "Number", data: number} | {kind: "String", data: string}; function handle(action: Action) { const {kind, data} = action; if (kind === "Number") { const square = (data * data); } else if (kind === "String") { const lines = data.split("\n"); } }
TypeScript 4.5 would not permit this code. The destructuring assignment (const {kind, data}
) created two independent variables; the compiler couldn’t understand that kind
being Number
means data
must be a number
type. Now it will recognize that fact, letting you use the destructuring syntax with discriminated unions.
Control flow analysis has also been tightened around dependent parameters. This syntax lets you specify complex rules for the nature of variadic parameters. Here’s a type definition for a function using this behavior:
type Func = (...args: ["Number", number], ["String", string]) => void;
This function’s signature specifies that you can either pass String
or Number
as its first parameter. If you use Number
, the next parameter must be a value of type number
. Alternatively, a string
can be given if it’s following String
.
Similarly to the discriminated unions example above, TypeScript now narrows the type of dependent parameters based on the values that preceded them:
const demo: Func = (kind, data) => { if (kind === "Number") { const square = (data * data); } else if (kind === "String") { const lines = data.split("\n"); } };
The compiler now appreciates that data
must be a number
if kind
is Number
. This code would have thrown an error with TypeScript 4.5.
Constructor Enhancements
The constructors of JavaScript classes that extend a parent must call super()
before the this
keyword can be used:
// Not allowed - "this" used before "super" class B extends A { constructor() { this.demo = "foobar"; super(); } } // Working correct order class C extends A { constructor() { super(); this.demo = "foobar"; } }
TypeScript’s historically been too strict in its enforcement of this requirement. Classes containing property initializers would be rejected if they had any code before the super()
statement, even if it never referred to this
:
const example = () => null; class C extends A { demoProperty = true; // Unnecessarily treated as invalid constructor() { example(); super(); } }
This handling helped to optimize TypeScript’s checks for genuine instances of this
being used before super()
. It also resulted in a lot of acceptable code failing to compile, forcing authors to refactor work that was actually valid JavaScript.
TypeScript 4.6 solves this issue. The compiler now falls in line with vanilla JavaScript by allowing code before super()
if it won’t result in this
being used. This gives you more freedom to write class constructors in the way that makes most sense for each situation. TypeScript will still detect any real cases of this
being referenced too early.
More Inference Improvements
Indexed access inferences are now more precise. This gives the compiler visibility into indexed access types which index to mapped objects. Although this was already possible before, older TypeScript releases produced poor quality inference which didn’t always have full awareness of the mapped object’s types.
TypeScript’s recursion depth checks have also been adjusted to enable better detection of incompatible recursive types. The change can improve type check performance as it facilitates earlier bail out when a type’s recursion begins to infinitely expand. The improvements focus on how recursion is applied to types that use generics.
ES2022 Targeting
The --target
flag has gained support for es2022
as a value. It enables full use of ES2022 features, ensuring syntax such as class fields and the Error.cause
property are preserved without transpilation in your stable builds.
You can target ES2022 by passing the --target es2022
flag to tsc
. Alternatively, change compilerOptions.target
to es2022
in your project’s tsconfig.json
file:
{ "compilerOptions": { "target": "es2022" } }
More JavaScript Syntax and Binding Errors
TypeScript now surfaces more standard JavaScript syntax and binding errors. These errors will show up during compilation and as you open files in your editor with the TypeScript extension for Visual Studio, Visual Studio Code, or Sublime Text installed.
Repeated const
statements, incorrect use of keywords, and scoping mistakes will now be surfaced by TypeScript, giving you immediate feedback as you work. The functionality can be disabled by adding a // @ts-nocheck
comment at the top of your source files.
This addition constitutes a breaking change as source files must now contain grammatically correct JavaScript. TypeScript’s compiler previously ignored most kinds of JavaScript syntax error. You should use the comment to turn off the feature if you think your codebase will be incompatible with this enforcement.
Another Breaking Change
There’s a second breaking change in this update: object rest expressions now drop non-spreadable members from generic objects. This improves consistency with the destructuring of non-generic types but means your existing variables may lack some properties they possessed in TypeScript 4.5.
Properties with non-spreadable values such as scalars and functions will be omitted from rest expressions. This also applies to other non-spreadable cases such as non-public members of class instances and this
. Code such as the following used to work but will now throw an error:
class Demo { prop = "example"; sayHello() { console.log("Hello World"); } methodWithRest() { const {prop, ...rest} = this; // ERROR - Non-spreadable value (function) will be dropped rest.sayHello(); } }
Summary
TypeScript 4.6 enhances type inference, improves child class constructor handling, and adds ES2022 as a supported output target. There are also a couple of narrow breaking changes in the form of expanded JavaScript syntax error detection and dropped non-spreadable object rest expression members. You can upgrade to the new release by running npm update typescript
or npm install typescript@latest
within your project’s working directory.
The update also marks the debut of an advanced new tool for analyzing TypeScript’s existing type generation traces. The Trace Analyzer works with the output from tsc --generateTrace
to help you pinpoint how complex type expressions are slowing down the compiler.
If you liked the article, do not forget to share it with your friends. Follow us on Google News too, click on the star and choose us from your favorites.
For forums sites go to Forum.BuradaBiliyorum.Com
If you want to read more like this article, you can visit our Technology category.