feat: add es2026 as a valid target and lib - #64096
Oleksandr Tarasiuk (a-tarasyuk) wants to merge 23 commits into
Conversation
fefecb3 to
a022dd9
Compare
There was a problem hiding this comment.
Pull request overview
Adds ES2026 compiler-target and standard-library support, including the APIs requested by #63704.
Changes:
- Registers
es2026as a target, default standard target, and library. - Adds ES2026 API declarations and preserves
esnext.*aliases. - Adds conformance tests and refreshes generated baselines.
Reviewed changes
Copilot reviewed 136 out of 540 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
packages/typescript/src/enums/scriptTarget*.ts |
Exposes ES2026 publicly. |
packages/typescript/test/{async,sync}/api.test.ts |
Updates target diagnostics. |
tsc/internal/core/{compileroptions,scripttarget_stringer_generated}.go |
Defines and formats the target. |
tsc/internal/tsoptions/enummaps.go |
Registers target, libraries, and compatibility aliases. |
tsc/internal/transformers/estransforms/definitions.go |
Selects the ES2026 transform pipeline. |
tsc/internal/checker/utilities.go |
Adds ES2026 library suggestions. |
tsc/internal/bundled/libs/lib.es2026*.d.ts |
Defines the ES2026 library and APIs. |
tsc/internal/bundled/libs/lib.esnext.d.ts |
Makes ESNext inherit ES2026. |
tsc/internal/bundled/{embed_generated,libs_generated}.go |
Embeds and registers new libraries. |
tsc/internal/compiler/program_test.go |
Updates expected ESNext library ordering. |
tsc/testdata/fixtures/compiler/*.ts |
Synchronizes compiler fixtures. |
tsc/testdata/tests/cases/conformance/es2026/*.ts |
Tests ES2026 APIs and diagnostics. |
tsc/testdata/baselines/reference/** |
Refreshes generated compiler, build, watch, API, and conformance baselines. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🔵 Needs a closer look
The public target and library surface spans hundreds of generated baselines and warrants final human validation against the ES2026 specification.
Review details
- Files reviewed: 136/540 changed files
- Comments generated: 0 new
- Review effort level: Balanced
| * Indicates whether the provided value is an object returned by `JSON.rawJSON()`. | ||
| * @param value The value to test. | ||
| */ | ||
| isRawJSON(value: unknown): value is RawJSON; |
There was a problem hiding this comment.
A bit funky that this is just an interface but I think that's just how it is?
There was a problem hiding this comment.
https://tc39.es/ecma262/2026/multipage/structured-data.html#sec-json.israwjson
https://tc39.es/ecma262/2026/multipage/structured-data.html#sec-json.rawjson
Maybe I’m missing something, but it seems like JSON.rawJSON() returns a regular object, and there’s no RawJSON constructor or global.
There was a problem hiding this comment.
Yeah, it's just one of those "it has an internal slot" things nobody can observe... Like who's to say I can't assign basically anything to RawJSON if it has rawJSON: string. But we can't do anything about it
There was a problem hiding this comment.
Yeah, I did wonder if it should be a class with a private field though. You can't forge this type.
There was a problem hiding this comment.
I’ve added a private field through a class.
declare class RawJSONBase {
private constructor();
private RawJSON_typekey: RawJSONBase;
}
interface RawJSON extends RawJSONBase {
readonly rawJSON: string;
}There was a problem hiding this comment.
Interesting, I had no idea this existed; the scripthost types are pretty legacy. Probably we should have deleted them....
I'm not sure what's right here, one I think needs a class to get nominality like this, but, we typically do not do this as it makes it impossible to extend lib later.
There was a problem hiding this comment.
I've switched back to using the interface. Both approaches have pros and cons, but I think the interface is a better fit here.
There was a problem hiding this comment.
one I think needs a class to get nominality like this, but, we typically do not do this as it makes it impossible to extend lib later.
We do this with Iterator in lib.es2025.iterator.d.ts.
// NOTE: This is specified as what is essentially an unreachable module. All actual global declarations can be found
// in the `declare global` section, below. This is necessary as there is currently no way to declare an `abstract`
// member without declaring a `class`, but declaring `class Iterator<T>` globally would conflict with TypeScript's
// general purpose `Iterator<T>` interface.
export {};
// Abstract type that allows us to mark `next` as `abstract`
declare abstract class Iterator<T, TResult = undefined, TNext = unknown> { // eslint-disable-line @typescript-eslint/no-unsafe-declaration-merging
abstract next(value?: TNext): IteratorResult<T, TResult>;
}
// ...
declare global {
// Global `IteratorConstructor` interface that can be augmented by polyfills
interface IteratorConstructor extends IteratorObjectConstructor {
/**
* Creates a native iterator from an iterator or iterable object.
* Returns its input if the input already inherits from the built-in Iterator class.
* @param value An iterator or iterable object to convert a native iterator.
*/
from<T>(value: Iterator<T, unknown, undefined> | Iterable<T, unknown, undefined>): IteratorObject<T, undefined, unknown>;
}
var Iterator: IteratorConstructor;
}There was a problem hiding this comment.
Yeah, I would slightly prefer to do the same here since we have precedent.
export {}
declare class RawJSONInstance {
#isRawJson: unknown;
readonly rawJSON: string;
}
declare global {
/**
* A frozen object containing JSON text for a primitive value, created by `JSON.rawJSON()`.
*/
interface RawJSON extends RawJSONInstance {
}
interface JSON {
/**
* Creates a frozen object containing JSON text for a primitive value.
* @param text Valid JSON text representing a string, number, boolean, or null value.
* @throws {SyntaxError} If `text` is not valid JSON text for a primitive value.
*/
rawJSON(text: string): RawJSON;
/**
* Indicates whether the provided value is an object returned by `JSON.rawJSON()`.
* @param value The value to test.
*/
isRawJSON(value: unknown): value is RawJSON;
}
}
let x: RawJSON = JSON.rawJSON("true");There was a problem hiding this comment.
Daniel Rosenwasser (@DanielRosenwasser) I've updated RawJSON
There was a problem hiding this comment.
🟡 Changes recommended
The jsonRawJSON2 source and checked-in baselines disagree, causing baseline tests to fail.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 146/553 changed files
- Comments generated: 1
- Review effort level: Balanced
…into feat/63704
| * Indicates whether the provided value is an object returned by `JSON.rawJSON()`. | ||
| * @param value The value to test. | ||
| */ | ||
| isRawJSON(value: unknown): value is RawJSON; |
There was a problem hiding this comment.
Yeah, I would slightly prefer to do the same here since we have precedent.
export {}
declare class RawJSONInstance {
#isRawJson: unknown;
readonly rawJSON: string;
}
declare global {
/**
* A frozen object containing JSON text for a primitive value, created by `JSON.rawJSON()`.
*/
interface RawJSON extends RawJSONInstance {
}
interface JSON {
/**
* Creates a frozen object containing JSON text for a primitive value.
* @param text Valid JSON text representing a string, number, boolean, or null value.
* @throws {SyntaxError} If `text` is not valid JSON text for a primitive value.
*/
rawJSON(text: string): RawJSON;
/**
* Indicates whether the provided value is an object returned by `JSON.rawJSON()`.
* @param value The value to test.
*/
isRawJSON(value: unknown): value is RawJSON;
}
}
let x: RawJSON = JSON.rawJSON("true");|
TypeScript Bot (@typescript-bot) test it |
|
Daniel Rosenwasser (@DanielRosenwasser) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Daniel Rosenwasser (@DanielRosenwasser) Here are the results of running the user tests with tsc comparing There were infrastructure failures potentially unrelated to your change:
Otherwise... Something interesting changed - please have a look. Details
|
|
Daniel Rosenwasser (@DanielRosenwasser) Here are the results of running the top 400 repos with tsc comparing Everything looks good! |
|
Hey Daniel Rosenwasser (@DanielRosenwasser), the results of running the DT tests are ready. Everything looks the same! |
Jake Bailey (jakebailey)
left a comment
There was a problem hiding this comment.
I don't think we typically add a slew of tests for lib files but, it's fine
Fixes #63704