TypeScript 4.9 has been officially released, and this version introduces several new features.

New in this version:

Here are some of the new features in detail:

New satisfies operator

One of the problems that TypeScript developers may encounter is to ensure that an expression matches some type, while preserving the concrete type of that expression. Example:


// Each property can be a string or an RGB tuple.
const palette = {
    red: [255, 0, 0],
    green: "#00ff00",
    bleu: [0, 0, 255]
//  ^^^^ sacrebleu - we've made a typo!
};

// We want to be able to use array methods on 'red'...
const redComponent = palette.red.at(0);

// or string methods on 'green'...
const greenNormalized = palette.green.toUpperCase();

It can be seen that blue is wrongly written as bleu, here you can try to use type annotations on the palette to catch the misspelling of bleu, but the information of each attribute will be lost.


type Colors = "red" | "green" | "blue";

type RGB = [red: number, green: number, blue: number];

const palette: Record<Colors, string | RGB> = {
    red: [255, 0, 0],
    green: "#00ff00",
    bleu: [0, 0, 255]
//  ~~~~ The typo is now correctly detected
};

// But we now have an undesirable error here - 'palette.red' "could" be a string.
const redComponent = palette.red.at(0);

The new satisfies operator can verify that the type of an expression matches a certain type without changing the result type of that expression. For example, you can use satisfies to verify that all properties of the palette match string | number[] compatible:


type Colors = "red" | "green" | "blue";

type RGB = [red: number, green: number, blue: number];

const palette = {
    red: [255, 0, 0],
    green: "#00ff00",
    bleu: [0, 0, 255]
//  ~~~~ The typo is now caught!
} satisfies Record<Colors, string | RGB>;

// Both of these methods are still accessible!
const redComponent = palette.red.at(0);
const greenNormalized = palette.green.toUpperCase();

satisfies can be used to catch many potential errors, such as ensuring an object has all keys of a certain type:


type Colors = "red" | "green" | "blue";

// Ensure that we have exactly the keys from 'Colors'.
const favoriteColors = {
    "red": "yes",
    "green": false,
    "blue": "kinda",
    "platypus": false
//  ~~~~~~~~~~ error - "platypus" was never listed in 'Colors'.
} satisfies Record<Colors, unknown>;

// All the information about the 'red', 'green', and 'blue' properties are retained.
const g: boolean = favoriteColors.green;

For more examples of satisfies, see the PR that raised this issue and implemented this operator.

Automatic accessors in classes

TypeScript 4.9 supports an upcoming feature in ECMAScript called automatic accessors, automatic accessors are declared just like properties of classes except they are declared with the accessor keyword.


class Person {
    accessor name: string;

    constructor(name: string) {
        this.name = name;
    }
}

Automatic accessors are converted to get and set accessors with inaccessible private properties.


class Person {
    #__name: string;

    get name() {
        return this.#__name;
    }
    set name(value: string) {
        this.#__name = name;
    }

    constructor(name: string) {
        this.name = name;
    }
}

Read the original PR about the feature.

An error is reported for direct comparison with NaN

Javascrpit’s NaN is a special numeric value that stands for “not a number”, and NaN is not equal to any value — not even itself.


console.log(NaN == 0)  // false
console.log(NaN === 0) // false
console.log(NaN == NaN)  // false
console.log(NaN === NaN) // false

This isn’t a JavaScript-specific problem, it’s true of any language that includes IEEE-754 floating point numbers. But JavaScript’s main number type is floating point number, many scenarios need to check for NaN, and the correct way is to use Number.isNaN to check for NaN type.

But here comes the problem, many novices will habitually use someValue === NaN to check. So TypeScript 4.9 introduces stricter warnings: direct comparisons with NaN will throw an error, and some variant of Number.isNaN will be suggested.


function validate(someValue: number) {
    return someValue !== NaN;
    //     ~~~~~~~~~~~~~~~~~
    // error: This condition will always return 'true'.
    //        Did you mean '!Number.isNaN(someValue)'?
}

File-Watching uses file system events

In earlier versions, TypeScript relied heavily on polling to see individual files. In TypeScript 4.9, file watches are powered by filesystem events by default, falling back to polling only if an event-based watcher fails to be set up.

For most developers, better performance will be experienced when running in –watch mode or with a TypeScript-supported editor such as Visual Studio or VS Code.

You can read more about this change on GitHub.

Introduce “remove unused imports” command

Previously, TypeScript only supported two editor commands to manage imports:


import { Zebra, Moose, HoneyBadger } from "./zoo";
import { foo, bar } from "./helper";

let x: Moose | HoneyBadger = foo();

The first one is called “Organization Import –Organize Imports“, it removes the unused imports, then sorts the rest. But it rewrites the file so that it looks like this:


import { foo } from "./helper";
import { HoneyBadger, Moose } from "./zoo";

let x: Moose | HoneyBadger = foo();

TypeScript 4.3 introduces a command called “Sort Imports”, which will only sort the imports in a file, but instead of removing the imports, it will rewrite the file like this:


import { bar, foo } from "./helper";
import { HoneyBadger, Moose, Zebra } from "./zoo";

let x: Moose | HoneyBadger = foo();

TypeScript 4.9 provides the “Remove Unused Imports” feature command, which will remove unused import names and statements, but preserve their relative order alone.


import { Moose, HoneyBadger } from "./zoo";
import { foo } from "./helper";

let x: Moose | HoneyBadger = foo();

Details of the feature can be viewed here.

go-to-definition functionality of the return keyword

When running go-to-definition on the return keyword, TypeScript will now jump to the top of the corresponding function, which helps to quickly understand which function the return belongs to.

TypeScript will extend this functionality to more keywords such as await and yield or switch, case and default.

Check out the original PR for the feature for more info.

Other details such as performance optimization and Bug Fixed can be found in the release announcement.

The new version can be obtained via NuGet, or using npm, via the following command:


npm install -D typescript

#TypeScript #released #satisfies #operator #News Fast Delivery

Leave a Comment

Your email address will not be published. Required fields are marked *