Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--erasableSyntaxOnly #61011

Merged
merged 14 commits into from
Jan 23, 2025
Merged

Conversation

RyanCavanaugh
Copy link
Member

Implements #59601

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Jan 22, 2025
@typescript-bot
Copy link
Collaborator

Looks like you're introducing a change to the public API surface area. If this includes breaking changes, please document them on our wiki's API Breaking Changes page.

Also, please make sure @DanielRosenwasser and @RyanCavanaugh are aware of the changes, just as a heads up.

@jakebailey
Copy link
Member

Reading #59601 (comment), do we also need to ban import foo = x.y? Or is that erasable?

@RyanCavanaugh
Copy link
Member Author

do we also need to ban import foo = x.y? Or is that erasable?

Modulo VMS restrictions, it always transforms to const foo = x.y, but I would not categorize this as an erasure

@jakebailey
Copy link
Member

ts-blank-space and Node both say no to import Foo = Bar.Baz, so that mostly settles it.

name: "erasableSyntaxOnly",
type: "boolean",
category: Diagnostics.Interop_Constraints,
description: Diagnostics.Do_not_allow_runtime_constructs_that_are_not_part_of_ECMAScript,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSX?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open to suggestions 🤷

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd vote no since that would curse anyone trying to use this for "purist" purposes to not being able to use JSX at all; you're already going to get an error from Node, and in other runtimes or with a loader, it might even work just fine....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the fact that you already have to put JSX content in a .?sx file means you can't possibly make the mistake of "not realizing enum is special" or whatever.

I thought Daniel wanted the text to say something different, which technically JSX is a non-ES runtime construct, but the phrasing would maybe get super awkward

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh that interpretation makes a lot more sense, oops

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're already going to get an error from Node

Well you could make the same argument about all of these features right?

the fact that you already have to put JSX content in a .?sx file

Well we permit JSX in JS files 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I think it is fine either way, just a slightly weird distinction.

Copy link
Member

@jakebailey jakebailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation seems right to me; cross checking with other tools, I don't believe we missed anything, but it might be a good idea to add a test that shows that namespaces need to be recursively checked.

tests/cases/compiler/erasableSyntaxOnly.ts Show resolved Hide resolved
tests/cases/compiler/erasableSyntaxOnly.ts Show resolved Hide resolved
tests/cases/compiler/erasableSyntaxOnlyDeclaration.ts Outdated Show resolved Hide resolved
@jakebailey
Copy link
Member

Worth re-noting for people watching this that ts-blank-space and Node.js' Amaro currently do not handle uninstantiated (type-only) namespaces:

@RyanCavanaugh RyanCavanaugh merged commit 2c865e4 into microsoft:main Jan 23, 2025
31 checks passed
@RyanCavanaugh RyanCavanaugh deleted the erasableSyntaxOnly branch January 23, 2025 23:56
@scottmas
Copy link

This disables ALL enums, but aren't string only enums 1 to 1 mappable to vanilla JavaScript? At runtime, as far as I can tell, a string enum behaves identical to an object composed of string values. Is this incorrect? And if not, would it be undesirable to allow string enums with this flag turned on? IMO string enums are far more ergonomic than const objects in that they are both a type and an iterable.

Sorry if this is irrelevant and the ship has sailed. Just thought I'd ask.

@ptts
Copy link

ptts commented Jan 25, 2025

This disables ALL enums, but aren't string only enums 1 to 1 mappable to vanilla JavaScript? At runtime, as far as I can tell, a string enum behaves identical to an object composed of string values. Is this incorrect? And if not, would it be undesirable to allow string enums with this flag turned on? IMO string enums are far more ergonomic than const objects in that they are both a type and an iterable.

Enums are not "erasable" syntax - they need to be transformed to become valid Javascript.

An enum like this:

// Typescript

enum Direction { 
  Up = "UP", 
  Down = "DOWN"
}

is transformed into

// Javascript

var Direction;
(function (Direction) {
    Direction["Up"] = "UP";
    Direction["Down"] = "DOWN";
})(Direction || (Direction = {}));

The flag introduced here aims at ensuring you get a type error when you write typescript syntax that is incompatible with Node's new type stripping feature (https://nodejs.org/en/learn/typescript/run-natively#running-typescript-code-with-nodejs), which enums are.

(There is a new --experimental-transform-types flag in Node which can handle enums)

@robpalme
Copy link

As @ptts says, erasable enums do not exist today.

There is a proposal to add them to TS via new as enum syntax here.

@mohsen1
Copy link
Contributor

mohsen1 commented Jan 25, 2025

@alexbit-codemod We need a codemod for this so everyone can migrate away easily!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

8 participants