microsoft/TypeScript

TypeScript 4.5 Iteration Plan

DanielRosenwasser opened this issue ยท 36 comments

This document outlines our focused tasks for TypeScript 4.5. It minimally indicates intent to investigate tasks or contribute to an implementation. Nothing is set in stone, but we will strive to complete these tasks in a reasonable timeframe.

Date Event
August 24th TypeScript 4.4 Release
September 24th Create 4.5 Beta (4.5.0) Build for Testing
September 28th TypeScript 4.5 Beta Release
October 29th Create 4.5 RC (4.5.1) Build for Testing
November 2nd TypeScript 4.5 RC Release
November 12th Create 4.5 Final (4.5.2) Build for Testing
November 16th TypeScript 4.5 Final Release ๐Ÿš€

Language and Compiler Features

Editor Productivity

Performance

Infrastructure

Website

DefinitelyTyped

The 4.4 Iteration Plan can be found at #44237

Thank you for all the work on TypeScript!

orta commented

#44964 - _ could_ be worth a sentence or two in the release notes

@typescript-bot create release-4.5

Heya @DanielRosenwasser, I've started to create the release-4.5 branch for you. Here's the link to my best guess at the log.

Heya @DanielRosenwasser, I've started to sync release-4.5 with main for you. Here's the link to my best guess at the log.

Heya @DanielRosenwasser, I've started to sync release-4.5 with main for you. Here's the link to my best guess at the log.

image

@typescript-bot sync release-4.5

Heya @DanielRosenwasser, I've started to sync release-4.5 with main for you. Here's the link to my best guess at the log.

Okay, 4th time's a charm. To save a bunch of time, I've deleted release-4.5 and we'll just recreate it now.

@typescript-bot create release-4.5

Heya @DanielRosenwasser, I've started to create the release-4.5 branch for you. Here's the link to my best guess at the log.

We did it! TypeScript 4.5 Beta is out, please give it a shot when you can.

Update: esModuleInterop behavior in node ESM previously required special flags, those are now default.
ESMI Playground with 4.5-beta: https://codesandbox.io/s/esmi-playground-k4ej2?file=/src/index.ts


Why is esModuleInterop turned on by default on module=node12? node12 supports ESM and the whole point of all of this is to let the Node module resolution do what it normally does... esModuleInterop hides problems that only get discovered after publishing to NPM and someone imports your definitions with esModuleInterop off.

Sandbox https://codesandbox.io/s/ts-http-ygsxh?file=/tsconfig.json

Why is esModuleInterop turned on by default on module=node12? node12 supports ESM and the whole point of all of this is to let the Node module resolution do what it normally does... esModuleInterop hides problems that only get discovered after publishing to NPM and someone imports your definitions with esModuleInterop off.

What do you mean? esModuleInterop is essentially correct for Node's official ESM support, generally people SHOULD be using esModuleInterop if they are emitting ESM for use in Node.

esModuleInterop hides problems that only get discovered after publishing to NPM and someone imports your definitions with esModuleInterop off.

They should use esModuleInterop, this is why tsc --init generates with it true by default. If you want to allow consuming with esModuleInterop: false then you can structure your package to include fallbacks, but honestly there's probably not going to be significant issues to just expect consumers to turn esModuleInterop on.

See #44501 for this particular addition of esModuleInterop to those and see #41139 for the general case of making it default everywhere (and discuss it in either of those or in another or a new issue rather than here?)

one weird edge case: seald/nedb#15

  1. index.js has module.exports = Datastore
  2. index.d.ts has export default Nedb
  3. package user can import with import { default as Datastore } but not import Datastore
    • unless export default is changed to export =

This looks like a type loading issue, not a node one

Sorry, this is probably not the right place to discuss bugs or UX issues with the Node12 resolution mode. Would you be willing to file separate issues?

I suppose since there is a lot of interest on this issue for the Node 12 resolution mode, I will link to #46452 and #46454 to give a status update on that. The short story is that the functionality will continue to work experimentally in nightlies, but will not ship in TypeScript 4.5 due to UX concerns.

@typescript-bot bump release-4.5

Heya @andrewbranch, I've started to update the version number on release-4.5 to 4.5.2 for you. Here's the link to my best guess at the log.

Use fs.realpathSync.native

If you want to further improve perf for resolving file paths/symlinks (and the file path is already normalized), it may be worth experimenting with platform-specific APIs like what Zig does in os.getFdPath.

In a microbenchmark on macOS that only resolves the same file path 100,000 times, the platform-specific API version is 1.4x faster when there is no symlink and 2x faster for symlinked files compared to using libc realpath (what fs.realpath.native does)

No symlink:

image

Symlink:

image

readlink-getfd.zig
const std = @import("std");

const path_handler = @import("../src/resolver/resolve_path.zig");
usingnamespace @import("../src/global.zig");

// zig build-exe -Drelease-fast --main-pkg-path ../ ./readlink-getfd.zig
pub fn main() anyerror!void {
    var stdout_ = std.io.getStdOut();
    var stderr_ = std.io.getStdErr();
    var output_source = Output.Source.init(stdout_, stderr_);
    Output.Source.set(&output_source);
    defer Output.flush();

    var args_buffer: [8096 * 2]u8 = undefined;
    var fixed_buffer = std.heap.FixedBufferAllocator.init(&args_buffer);
    var allocator = &fixed_buffer.allocator;

    var args = std.mem.span(try std.process.argsAlloc(allocator));

    const to_resolve = args[args.len - 1];
    const cwd = try std.process.getCwdAlloc(allocator);
    var path: []u8 = undefined;
    var out_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;

    var j: usize = 0;
    while (j < 100000) : (j += 1) {
        var parts = [1][]const u8{std.mem.span(to_resolve)};
        var joined_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
        var joined = path_handler.joinAbsStringBuf(
            cwd,
            &joined_buf,
            &parts,
            .loose,
        );
        joined_buf[joined.len] = 0;
        const joined_z: [:0]const u8 = joined_buf[0..joined.len :0];

        var file = std.fs.openFileAbsoluteZ(joined_z, .{ .read = false }) catch |err| {
            switch (err) {
                error.NotDir, error.FileNotFound => {
                    Output.prettyError("<r><red>404 Not Found<r>: <b>\"{s}\"<r>", .{joined_z});
                    Output.flush();
                    std.process.exit(1);
                },
                else => {
                    return err;
                },
            }
        };

        path = try std.os.getFdPath(file.handle, &out_buffer);
        file.close();
    }

    Output.print("{s}", .{path});
}
readlink-realpath.zig
const std = @import("std");

const path_handler = @import("../src/resolver/resolve_path.zig");
usingnamespace @import("../src/global.zig");

// zig build-exe -Drelease-fast --main-pkg-path ../ ./readlink-realpath.zig
pub fn main() anyerror!void {
    var stdout_ = std.io.getStdOut();
    var stderr_ = std.io.getStdErr();
    var output_source = Output.Source.init(stdout_, stderr_);
    Output.Source.set(&output_source);
    defer Output.flush();

    var args_buffer: [8096 * 2]u8 = undefined;
    var fixed_buffer = std.heap.FixedBufferAllocator.init(&args_buffer);
    var allocator = &fixed_buffer.allocator;

    var args = std.mem.span(try std.process.argsAlloc(allocator));

    const to_resolve = args[args.len - 1];
    const cwd = try std.process.getCwdAlloc(allocator);
    var out_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
    var path: []u8 = undefined;

    var j: usize = 0;
    while (j < 100000) : (j += 1) {
        path = try std.os.realpathZ(to_resolve, &out_buffer);
    }

    Output.print("{s}", .{path});
}

I imagine the platform-specific API version is faster because it replaces a while loop that does several syscalls with 1-3 syscalls

Heya @DanielRosenwasser, I've started to update the version number on release-4.5 to 4.5.3 for you. Here's the link to my best guess at the log.

Cancelled. Missed a PR.

Heya @DanielRosenwasser, I've started to update the version number on release-4.5 to 4.5.3 for you. Here's the link to my best guess at the log.

Where can we find the release notes for 4.5.3? I didn't quite understand how to interpret the typescript-bot links.

The GitHub releases view is updated, just look up the relevant milestone (TypeScript 4.5.3 in this case) for future reference.

Creating a 4.5.4 now to also address #47090

@typescript-bot bump release-4.5

Heya @DanielRosenwasser, I've started to update the version number on release-4.5 to 4.5.4 for you. Here's the link to my best guess at the log.

Heya @DanielRosenwasser, I've started to update the version number on release-4.5 to 4.5.5 for you. Here's the link to my best guess at the log.