Fundamentals 10 min read

TypeScript 5.8 Beta Arrives with Native require‑ESM Support

The TypeScript 5.8 beta introduces function‑type inference improvements, native require‑ESM loading via --module nodenext, experimental Node.js flags for stripping types and transforming syntax, variable‑initialization checks back‑ported from 5.7, and the removal of computed‑property literal restrictions, all installable via npm or VS Code.

Full-Stack Cultivation Path
Full-Stack Cultivation Path
Full-Stack Cultivation Path
TypeScript 5.8 Beta Arrives with Native require‑ESM Support

Install the TypeScript 5.8 beta with npm install typescript@beta or via VS Code’s JavaScript and TypeScript Nightly extension by selecting the beta version for the workspace.

Function type inference optimization

When a function’s return type should depend on a parameter, overloads are often used, but overloads have two drawbacks: the implementation is not checked against each overload signature, and many overloads make the signature hard to read.

enum ValueKind { Single, Multiple }

async function getValue(value: ValueKind): Promise<string | string[]> {
  if (value === ValueKind.Single) {
    return '';
  } else {
    return [];
  }
}

// Overload attempt
async function getValue(value: ValueKind.Single): Promise<string>;
async function getValue(value: ValueKind.Multiple): Promise<string[]>;
async function getValue(value: ValueKind): Promise<string | string[]> { /* ... */ }

Because the implementation can return a value that does not satisfy the overload declaration, TypeScript does not emit an error.

A naïve conditional‑type definition

type ReturnValue<S extends ValueKind> = S extends ValueKind.Multiple ? string[] : string;

causes an error inside the function body because the generic S is not yet resolved.

TypeScript 4.8 introduced type narrowing inside the function body, enabling a refined conditional type:

type ReturnValue<S extends ValueKind> =
  S extends ValueKind.Multiple ? string[] :
  S extends ValueKind.Single ? string :
  never;

async function getValue<S extends ValueKind>(value: S): Promise<ReturnValue<S>> {
  if (value === ValueKind.Single) {
    return '';
  } else {
    return [];
  }
}

This ties the return type to the argument type without overloads.

Require ESM support

Node.js 22 adds experimental support for loading ECMAScript modules with require. TypeScript 5.8 enables this behavior when the compiler option --module nodenext is set. Fine‑grained flags such as --module node18 are not yet provided.

Node.js TS support – --erasableSyntaxOnly

Node.js 22.6.0 introduced the experimental flag --experimental-strip-types, allowing direct execution of .ts files. From Node.js 23.6.0 the flag is on by default, with --no-experimental-strip-types to disable it.

The implementation uses the Amaro runtime, which relies on @swc/wasm-typescript to strip type‑only syntax:

const amaro = require('amaro');
const { code } = amaro.transformSync("const foo: string = 'bar';", { mode: "strip-only" });
console.log(code); // "const foo = 'bar';"

Some TypeScript constructs, such as enums, cannot be stripped. Node.js 23.7.0 adds the experimental flag --experimental-transform-types (mode transform) to perform a pre‑execution transformation, exposing errors like:

SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode
   1 | enum ValueKind {
   2 |   Single,
   3 |   Multiple,
   4 | }

To help developers detect such code before stripping, TypeScript 5.8 adds the compiler option --erasableSyntaxOnly.

Variable initialization checking (back‑ported from 5.7)

Since version 5.7, TypeScript warns when a variable is read before being definitely assigned across function boundaries:

function foo() {
  let result: number;
  function printResult() {
    console.log(result); // error from 5.7 onward
  }
}

Computed property type declaration optimization

Earlier TypeScript required computed property names in class declarations to be literal or unique‑symbol types. Using a mutable let string caused an error, while a const declaration narrowed the type to a literal and avoided the error.

Version 5.8 removes this restriction, allowing let declarations without error and producing the same declaration output as const:

export let propName = 'theAnswer';
export class MyClass {
  [propName] = 42;
}

The emitted declaration is equivalent to the const case:

export const propName = 'theAnswer';
export class MyClass {
  [propName] = 42;
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

TypeScriptNode.jsConditional TypesType InferenceBetarequire(esm)
Full-Stack Cultivation Path
Written by

Full-Stack Cultivation Path

Focused on sharing practical tech content about TypeScript, Vue 3, front-end architecture, and source code analysis.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.