🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
1 Tag Serie
🔧 Programmierung 🕛 kürzlich 25 Min Lesezeit
0

Announcing TypeScript 3.7

↗ Quelle (devblogs.microsoft.com)
🗣️ Stimme:
📑 Inhaltsübersicht

We’re thrilled to announce the release of TypeScript 3.7, a release packed with awesome new language, compiler, and tooling features.


If you haven’t yet heard of TypeScript, it’s a language based on JavaScript that adds static type-checking along with type syntax. Static type-checking lets us know about problems with our code before we try to run it by reporting errors if we do something questionable. This ranges from type coercions that can happen in code like 42 / "hello", or even basic typos on property names. But beyond this, TypeScript powers things like completions, quick fixes, and refactorings for both TypeScript and JavaScript in some of your favorite editors. In fact, if you already use Visual Studio or Visual Studio Code, you might already be using TypeScript when you write JavaScript code! So if you’re interested in learning more, , or use npm with the following command:



CODE
npm install typescript


You can also get editor support by












  • where we’ve added an entire menu for learning what’s new.


    A screenshot of the TypeScript playground which now has a section for learning what's new.


    Without further ado, let’s dive in and look at what’s new!



    Optional Chaining


    TypeScript 3.7 implements one of the most highly-demanded ECMAScript features yet: optional chaining!


    Optional chaining is and (if it ever was); however, it has a bug because it uses ||.



    CODE
    function initializeAudio() {
    let volume = localStorage.volume || 0.5

    // ...
    }


    When localStorage.volume is set to 0, the page will set the volume to 0.5 which is unintended. ?? avoids some unintended behavior from 0, NaN and "" being treated as falsy values.


    We owe a large thanks to community members for implementing this feature! For more details, .



    Assertion Functions


    There’s a specific set of functions that throw an error if something unexpected happened. They’re called “assertion” functions. As an example, Node.js has a dedicated function for this called assert.



    CODE
    assert(someValue === 42);


    In this example if someValue isn’t equal to 42, then assert will throw an AssertionError.


    Assertions in JavaScript are often used to guard against improper types being passed in. For example,



    CODE
    function multiply(x, y) {
    assert(typeof x === "number");
    assert(typeof y === "number");

    return x * y;
    }


    Unfortunately in TypeScript these checks could never be properly encoded. For loosely-typed code this meant TypeScript was checking less, and for slightly conservative code it often forced users to use type assertions..



    CODE
    function yell(str) {
    assert(typeof str === "string");

    return str.toUppercase();
    // Oops! We misspelled 'toUpperCase'.
    // Would be great if TypeScript still caught this!
    }


    The alternative was to instead rewrite the code so that the language could analyze it, but this isn’t convenient.



    CODE
    function yell(str) {
    if (typeof str !== "string") {
    throw new TypeError("str should have been a string.")
    }
    // Error caught!
    return str.toUppercase();
    }


    Ultimately the goal of TypeScript is to type existing JavaScript constructs in the least disruptive way. For that reason, TypeScript 3.7 introduces a new concept called “assertion signatures” which model these assertion functions.


    The first type of assertion signature models the way that Node’s assert function works. It ensures that whatever condition is being checked must be true for the remainder of the containing scope.



    CODE
    function assert(condition: any, msg?: string): asserts condition {
    if (!condition) {
    throw new AssertionError(msg)
    }
    }


    asserts condition says that whatever gets passed into the condition parameter must be true if the assert returns (because otherwise it would throw an error). That means that for the rest of the scope, that condition must be truthy. As an example, using this assertion function means we do catch our original yell example.



    CODE
    function yell(str) {
    assert(typeof str === "string");

    return str.toUppercase();
    // ~~~~~~~~~~~
    // error: Property 'toUppercase' does not exist on type 'string'.
    // Did you mean 'toUpperCase'?
    }

    function assert(condition: any, msg?: string): asserts condition {
    if (!condition) {
    throw new AssertionError(msg)
    }
    }


    The other type of assertion signature doesn’t check for a condition, but instead tells TypeScript that a specific variable or property has a different type.



    CODE
    function assertIsString(val: any): asserts val is string {
    if (typeof val !== "string") {
    throw new AssertionError("Not a string!");
    }
    }


    Here asserts val is string ensures that after any call to assertIsString, any variable passed in will be known to be a string.



    CODE
    function yell(str: any) {
    assertIsString(str);

    // Now TypeScript knows that 'str' is a 'string'.

    return str.toUppercase();
    // ~~~~~~~~~~~
    // error: Property 'toUppercase' does not exist on type 'string'.
    // Did you mean 'toUpperCase'?
    }


    These assertion signatures are very similar to writing type predicate signatures:



    CODE
    function isString(val: any): val is string {
    return typeof val === "string";
    }

    function yell(str: any) {
    if (isString(str)) {
    return str.toUppercase();
    }
    throw "Oops!";
    }


    And just like type predicate signatures, these assertion signatures are incredibly expressive. We can express some fairly sophisticated ideas with these.



    CODE
    function assertIsDefined<T>(val: T): asserts val is NonNullable<T> {
    if (val === undefined || val === null) {
    throw new AssertionError(
    `Expected 'val' to be defined, but received ${val}`
    );
    }
    }


    To read up more about assertion signatures, is specified to return never.


    In order to ensure that a function never potentially returned undefined or effectively returned from all code paths, TypeScript needed some syntactic signal – either a return or throw at the end of a function. So users found themselves return-ing their failure functions.



    CODE
    function dispatch(x: string | number): SomeType {
    if (typeof x === "string") {
    return doThingWithString(x);
    }
    else if (typeof x === "number") {
    return doThingWithNumber(x);
    }
    return process.exit(1);
    }


    Now when these never-returning functions are called, TypeScript recognizes that they affect the control flow graph and accounts for them.



    CODE
    function dispatch(x: string | number): SomeType {
    if (typeof x === "string") {
    return doThingWithString(x);
    }
    else if (typeof x === "number") {
    return doThingWithNumber(x);
    }
    process.exit(1);
    }


    As with assertion functions, you can .



    (More) Recursive Type Aliases


    Type aliases have always had a limitation in how they could be “recursively” referenced. The reason is that any use of a type alias needs to be able to substitute itself with whatever it aliases. In some cases, that’s not possible, so the compiler rejects certain recursive aliases like the following:



    CODE
    type Foo = Foo;


    This is a reasonable restriction because any use of Foo would need to be replaced with Foo which would need to be replaced with Foo which would need to be replaced with Foo which… well, hopefully you get the idea! In the end, there isn’t a type that makes sense in place of Foo.


    This is fairly .



    The useDefineForClassFields Flag and The declare Property Modifier


    Back when TypeScript implemented public class fields, we assumed to the best of our abilities that the following code



    CODE
    class C {
    foo = 100;
    bar: string;
    }


    would be equivalent to a similar assignment within a constructor body.



    CODE
    class C {
    constructor() {
    this.foo = 100;
    }
    }


    Unfortunately, while this seemed to be the direction that the proposal moved towards in its earlier days, there is an extremely strong chance that public class fields will be standardized differently. Instead, the original code sample might need to de-sugar to something closer to the following:



    CODE
    class C {
    constructor() {
    Object.defineProperty(this, "foo", {
    enumerable: true,
    configurable: true,
    writable: true,
    value: 100
    });
    Object.defineProperty(this, "bar", {
    enumerable: true,
    configurable: true,
    writable: true,
    value: void 0
    });
    }
    }


    While TypeScript 3.7 isn’t changing any existing emit by default, we’ve been rolling out changes incrementally to help users mitigate potential future breakage. We’ve provided a new flag called useDefineForClassFields to enable this emit mode with some new checking logic.


    The two biggest changes are the following:


    • Declarations are initialized with Object.defineProperty.

    • Declarations are always initialized to undefined, even if they have no initializer.

    This can cause quite a bit of fallout for existing code that use inheritance. First of all, set accessors from base classes won’t get triggered – they’ll be completely overwritten.



    CODE
    class Base {
    set data(value: string) {
    console.log("data changed to " + value);
    }
    }

    class Derived extends Base {
    // No longer triggers a 'console.log'
    // when using 'useDefineForClassFields'.
    data = 10;
    }


    Secondly, using class fields to specialize properties from base classes also won’t work.



    CODE
    interface Animal { animalStuff: any }
    interface Dog extends Animal { dogStuff: any }

    class AnimalHouse {
    resident: Animal;
    constructor(animal: Animal) {
    this.resident = animal;
    }
    }

    class DogHouse extends AnimalHouse {
    // Initializes 'resident' to 'undefined'
    // after the call to 'super()' when
    // using 'useDefineForClassFields'!
    resident: Dog;

    constructor(dog: Dog) {
    super(dog);
    }
    }


    What these two boil down to is that mixing properties with accessors is going to cause issues, and so will re-declaring properties with no initializers.


    To detect the issue around accessors, TypeScript 3.7 will now emit get/set accessors in .d.ts files so that TypeScript can check for overridden accessors.


    Code that’s impacted by the class fields change can get around the issue by converting field initializers to assignments in constructor bodies.



    CODE
    class Base {
    set data(value: string) {
    console.log("data changed to " + value);
    }
    }

    class Derived extends Base {
    constructor() {
    this.data = 10;
    }
    }


    To help mitigate the second issue, you can either add an explicit initializer or add a declare modifier to indicate that a property should have no emit.



    CODE
    interface Animal { animalStuff: any }
    interface Dog extends Animal { dogStuff: any }

    class AnimalHouse {
    resident: Animal;
    constructor(animal: Animal) {
    this.resident = animal;
    }
    }

    class DogHouse extends AnimalHouse {
    declare resident: Dog;
    // ^^^^^^^
    // 'resident' now has a 'declare' modifier,
    // and won't produce any output code.

    constructor(dog: Dog) {
    super(dog);
    }
    }


    Currently useDefineForClassFields is only available when targeting ES5 and upwards, since Object.defineProperty doesn’t exist in ES3. To achieve similar checking for issues, you can create a seperate project that targets ES5 and uses --noEmit to avoid a full build.


    For more information, you can .



    Uncalled Function Checks


    A common and dangerous error is to forget to invoke a function, especially if the function has zero arguments or is named in a way that implies it might be a property rather than a function.



    CODE
    interface User {
    isAdministrator(): boolean;
    notify(): void;
    doNotDisturb?(): boolean;
    }

    // later...

    // Broken code, do not use!
    function doAdminThing(user: User) {
    // oops!
    if (user.isAdministrator) {
    sudo();
    editTheConfiguration();
    }
    else {
    throw new AccessDeniedError("User is not an admin");
    }
    }


    Here, we forgot to call isAdministrator, and the code incorrectly allows non-adminstrator users to edit the configuration!


    In TypeScript 3.7, this is identified as a likely error:



    CODE
    function doAdminThing(user: User) {
    if (user.isAdministrator) {
    // ~~~~~~~~~~~~~~~~~~~~
    // error! This condition will always return true since the function is always defined.
    // Did you mean to call it instead?


    This check is a breaking change, but for that reason the checks are very conservative. This error is only issued in if conditions, and it is not issued on optional properties, if strictNullChecks is off, or if the function is later called within the body of the if:



    CODE
    interface User {
    isAdministrator(): boolean;
    notify(): void;
    doNotDisturb?(): boolean;
    }

    function issueNotification(user: User) {
    if (user.doNotDisturb) {
    // OK, property is optional
    }
    if (user.notify) {
    // OK, called the function
    user.notify();
    }
    }


    If you intended to test the function without calling it, you can correct the definition of it to include undefined/null, or use !! to write something like if (!!user.isAdministrator) to indicate that the coercion is intentional.


    We owe a big thanks to GitHub user and iterated to provide us with with ), so now in TypeScript 3.7, errors like this are flattened to a message like the following:


    CODE
    Type 'SomeVeryBigType' is not assignable to type 'AnotherVeryBigType'.
    The types returned by 'a.b.c.d.e.f()' are incompatible between these types.
    Type 'string' is not assignable to type 'number'.

    For more details, , and will be available in Visual Studio 16.4 Preview 2 in the Tools Options menu.


    New semicolon formatter option in VS Code


    Choosing a value of “insert” or “remove” also affects the format of auto-imports, extracted types, and other generated code provided by TypeScript services. Leaving the setting on its default value of “ignore” makes generated code match the semicolon preference detected in the current file.



    Website and Playground Updates


    We’ll be talking more about this in the near future, but if you haven’t seen it already, you should check out the significantly upgraded .


    As a cherry on top, outside of the handbook we now have search powered by Algolia on the website, allowing you to search through the handbook, release notes, and more!


    Search on the TypeScript website.


    . These changes are largely correctness changes related to nullability, but impact will ultimately depend on your codebase.



    Class Field Mitigations


    .



    Function Truthy Checks


    As mentioned above, TypeScript now errors when functions appear to be uncalled within if statement conditions. An error is issued when a function type is checked in if conditions unless any of the following apply:


    • the checked value comes from an optional property

    • strictNullChecks is disabled

    • the function is later called within the body of the if


    Local and Imported Type Declarations Now Conflict


    Due to a bug, the following construct was previously allowed in TypeScript:



    CODE
    // ./someOtherModule.ts
    interface SomeType {
    y: string;
    }

    // ./myModule.ts
    import { SomeType } from "./someOtherModule";
    export interface SomeType {
    x: number;
    }

    function fn(arg: SomeType) {
    console.log(arg.x); // Error! 'x' doesn't exist on 'SomeType'
    }


    Here, SomeType appears to originate in both the import declaration and the local interface declaration. Perhaps surprisingly, inside the module, SomeType refers exclusively to the imported definition, and the local declaration SomeType is only usable when imported from another file. This is very confusing and our review of the very small number of cases of code like this in the wild showed that developers usually thought something different was happening.


    In TypeScript 3.7, , and we’ll be updating our rolling feature appeared first on TypeScript.

    Vollständiger Original-Bericht
    Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf devblogs.microsoft.com.
    ↗ Original-Artikel auf devblogs.microsoft.com lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage