TypeScript 5.7 varsler deg om enda flere tabber

Her er tre av de viktigste nyhetene i TypeScript 5.7.

TypeScript 5.7 kan oppdage enda flere kodeblemmer. 📸: <a href="https://unsplash.com/@flipsnack?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Flipsnack</a> / <a href="https://unsplash.com/photos/two-men-sitting-in-front-of-a-laptop-computer-Hp4RPL_Z6wE?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Unsplash</a>
TypeScript 5.7 kan oppdage enda flere kodeblemmer. 📸: Flipsnack / Unsplash Vis mer

Microsoft har lansert betaversjonen av TypeScript 5.7.

Som vanlig er det en masse nytt også i denne versjonen, og i likhet med TypeScript 5.6 handler mange av nyhetene om å varsle deg om kodetabber som kanskje ikke alltid er lett å få øye på.

I TypeScript 5.7 har språkets typesystem blitt bedre på å varsle deg når du har definert en variabel, men ikke initialisert den – altså ikke gitt den en verdi, slik at den er "undefined".

Her er tre av nyhetene:

#1: Skjønner når du bruker ikke-initialiserte variabler

Ifølge Microsoft har TypeScript lenge vært i stand til å fange opp tilfeller der du risikerer at en variabel ikke er initialisert (tilordnet en verdi). Men dette har nå blitt bedre.

I kodeeksempelet under vil variabelen være "undefined" hvis "someCondition" gjør at du når else-delen av koden (der det mangler en result = temporaryWork;). Også tidligere versjoner av TypeScript skjønner da at result i noen tilfeller ikke vil være tilordnet noen verdi.

let result: number
if (someCondition()) {
    result = doSomeWork();
}
else {
    let temporaryWork = doSomeWork();
    temporaryWork *= 2;
    // forgot to assign to 'result'
}

console.log(result); // error: Variable 'result' is used before being assigned.

Men i noen tilfeller har ikke denne analysen fungert helt.

Det gjelder for eksempel hvis variabelen blir brukt i en separat funksjon. Da vet ikke typesystemet når funksjonen vil bli kalt, og vil derfor "optimistisk" anta at variabelen vil bli initialisert.

function foo() {
    let result: number
    if (someCondition()) {
        result = doSomeWork();
    }
    else {
        let temporaryWork = doSomeWork();
        temporaryWork *= 2;
        // forgot to assign to 'result'
    }

    printResult();

    function printResult() {
        console.log(result); // no error here.
    }
}

– Selv om TypeScript 5.7 fortsatt vil være fleksibel med hensyn til variabler som kanskje har blitt initialisert, er typesystemet i stand til å rapportere feil når variabler aldri har blitt initialisert i det hele tatt, skriver Microsoft.

Denne kodesnutten vil derfor fra og med TypeScript 5.7 gi deg en advarsel:

function foo() {
    let result: number
    
    // do work, but forget to assign to 'result'

    function printResult() {
        console.log(result); // error: Variable 'result' is used before being assigned.
    }
}

På tide å skrive om funksjonen til noe litt mer robust!

#2: Bedre støtte for å kjøre TS-filer rett fra kommandolinjen

Det finnes flere verktøy og kjøremiljøer som lar deg kjøre TypeScript-kode uten at du trenger noe byggesteg. For eksempel kan du bruke ts-node til å kjøre en TypeScript-fil direkte ved å skrive for eksempel ts-node script.ts, og du har også tilsvarende muligheter i Deno og Bun. Og nylig kom også Node.js med eksperimentell støtte for å automatisk strippe vekk TypeScript-typer fra .ts-filer.

Mulighet til å kjøre TypeScript-kode "in-place" kan være nyttig fordi det lar deg iterere kjappere, uten å måtte kjøre et byggesteg på nytt hver gang du vil sjekke om noe fungerer eller ikke.

Dessverre er det ikke alltid dette har fungert. Microsoft skriver at for å være mest mulig kompatibelt med alle de ulike verktøyene som lar deg kjøre TypeScript-kode direkte, så må alle TypeScript-filer importeres med den riktige TypeScript-filendelsen. For eksempel slik i Node.js nye eksperimentelle støtte for TypeScript:

// main.ts

import * as foo from "./foo.ts"; // <- we need foo.ts here, not foo.js

Dette ville frem til nå ha resultert i en feilmelding fra TypeScript, siden den forventer at vi importerer output-filen. Men siden enkelte verktøy faktisk støtter import av filer med .ts-endelse, har TypeScript støttet det via valget --allowImportingTsExtensions en stund.

Noen ganger vil man imidlertid generere .js-filer av .ts-filene.

– Dette er et krav for bibliotekforfattere som må kunne distribuere bare .js-filer, men hittil har TypeScript unngått å omskrive filstier, skriver Microsoft.

Derfor har de nå lagt til et nytt kompilatorvalg kalt --rewriteRelativeImportExtensions som automatisk vil skrive om filendelsene på denne måten:

// Under --rewriteRelativeImportExtensions...

// these will be rewritten.
import * as foo from "./foo.ts";
import * as bar from "../someFolder/bar.mts";

// these will NOT be rewritten in any way.
import * as a from "./foo";
import * as b from "some-package/file.ts";
import * as c from "@some-scope/some-package/file.ts";
import * as d from "#/file.ts";
import * as e from "./file.js";

Du kan lese mer om dette og hvordan det fungerer her.

#3: Og den er kjappere!

Du kan lese om alle nyhetene i TypeScript 5.7 i lanseringsbloggposten. Som at den har blitt flinkere til å finne "riktig" tsconfig.json-fil hvis du bruker kodeeditorer som bruker TSServer, for eksempel Visual Studio eller VS Code.

Til slutt nevner vi også at TypeScript 5.7 har fått støtte for et nytt API i Node.js 22 som lar Node.js cache en del av det som gjøres første gang et verktøy kjøres.

– TypeScript 5.7 bruker dette API-et slik at den kan begynne å gjøre noe nyttig tidligere, skriver Microsoft.