Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

--erasableSyntaxOnly#61011

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

RyanCavanaugh
Copy link
Member

Implements#59601

petamoriken, marco-ippolito, peter-leonov, robpalme, shrujalshah28, mpal9000, zanminkian, theoludwig, Bnaya, nicojs, and 22 more reacted with thumbs up emojimarco-ippolito, Bnaya, wojtekmaj, RamonBalthazar, johndjameson, lin72h, nickserv, friday, codyzu, btoo, and 6 more reacted with hooray emojimarco-ippolito, marcomuser, Bnaya, aaronccasanova, Peterclark1996, ni554n, RamonBalthazar, friday, lin72h, codyzu, and 6 more reacted with heart emojimarco-ippolito, Bnaya, mxdvl, RamonBalthazar, lin72h, friday, btoo, kachkaev, and roottool reacted with rocket emojikt3k, Bnaya, ChrisChou-freeman, and hellbilly13source reacted with eyes emoji
@typescript-bottypescript-bot added Author: Team For Uncommitted BugPR for untriaged, rejected, closed or missing bug labelsJan 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 themon our wiki's API Breaking Changes page.

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

mxdvl reacted with laugh emoji

@jakebailey
Copy link
Member

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

zanminkian reacted with thumbs up emoji

@RyanCavanaugh
Copy link
MemberAuthor

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

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

@jakebailey
Copy link
Member

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

ljharb, avivdy, and zanminkian reacted with thumbs up emoji

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

Choose a reason for hiding this comment

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

JSX?

Copy link
MemberAuthor

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
MemberAuthor

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 JSXis 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

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 😄

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

@jakebaileyjakebailey 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.

@jakebailey
Copy link
Member

@RyanCavanaughRyanCavanaugh merged commit2c865e4 intomicrosoft:mainJan 23, 2025
31 checks passed
@RyanCavanaughRyanCavanaugh deleted the erasableSyntaxOnly branchJanuary 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 commentedJan 25, 2025
edited
Loading

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:

// TypescriptenumDirection{Up="UP",Down="DOWN"}

is transformed into

// JavascriptvarDirection;(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 whichcan handle enums)

@robpalme
Copy link

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

There is a proposal to add them to TS via newas enum syntaxhere.

@mohsen1
Copy link
Contributor

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

alexbit-codemod and amirabbas-gh reacted with thumbs up emoji

acutmore added a commit to bloomberg/ts-blank-space that referenced this pull requestJan 29, 2025
This PR adds support for type-only/uninstantiated namespaces. i.e.namespaces that only use `type` and `interface`.```tsexport class C {}export namespace C {  export type T = string;}```**Before:** Error. only `declare namespace ...` was allowed ❌ **Now:** Ok. namespace declaration erased ✅ ---The following cases remain unchanged:```ts// Instantiated namespace errorsnamespace A { export let x = 1 }                // errornamespace B { ; }                               // error// Ambient namespace is eraseddeclare namespace C { export let x = 1 }        // ok eraseddeclare module    D { export let x = 1 }        // ok erased// `module`-keyword errorsmodule E { export let x = 1 }                   // errormodule F { export type x = number }             // error```## TestingUnit tests for both supported cases and unsupported cases (errors) havebeen added.## ContextThis addition was motivated by[`--erasableSyntaxOnly`](microsoft/TypeScript#61011)and the recognition that in today's TypeScript, the only way to augmenta class with types after the initial declaration is via namespaces.Whilst that use case can be solved using `declare namespace` that comeswith [ahazard](https://github.com/bloomberg/ts-blank-space/blob/main/docs/unsupported_syntax.md#the-declare--hazard).The combination of `--erasableSyntaxOnly` checks and transforminguninstantiated namespaces provides a safer option.Thanks to@jakebailey for brining this to our attentionmicrosoft/TypeScript#61011 (comment)---------Signed-off-by: Ashley Claymore <aclaymore@bloomberg.net>Co-authored-by: Rob Palmer <rob.palmer2@gmail.com>
@rauschma
Copy link

Should this option imply--verbatimModuleSyntax?

zanminkian reacted with thumbs up emoji

@jakebailey
Copy link
Member

We discussed this heavily and settled on "no" for now, mainly because it makes our implied options complexity even worse, but also because it means those who are using this flag for reasons that aren'tspecifically needing the emit then have to disable some other flag (or if we made it required, be stuck).

rauschma and RyanCavanaugh reacted with thumbs up emoji

@demurgos
Copy link

demurgos commentedMar 6, 2025
edited
Loading

I'm coming here fromthe 5.8 announcement, looking for how to migrate from enums when usingerasableSyntaxOnly.

A popular solution that I see is using anas const object (e.g.as documented in the handbook).

// you can also use number literalsconstMyEnum={Foo:"Foo",Bar:"Bar",}asconst;

This is usually accompanied withexport type (e.g. as intheas enum proposal):export type MyEnum = typeof MyEnum[keyof typeof NodeType];

This lets you useMyEnum as a type representing the union of the variant values (heretype MyEnum = "Foo" | "Bar") and on the value side you can useMyEnum.Foo orMyEnum.Bar.
There are a few downsides though:

  • You lose nominal typing since the typeMyEnum is now equivalent to the string literal union, consumer can pass"Foo" directly as a literal (instead of explicitly usingMyEnum.Foo).
  • You can't refer to the variant type throughMyEnum.Foo, this is mainly an issue when using the enum as the tag of a discriminated union
  • Unless you use the variant name as the variant value, debugging is less convenient because there's no reverse mapping

I don't really care about the last point, and it's easy to use the variant name anyway (it will most likely be interned by the JS engine, so perf should not be a big concern when comparing using a number VS a short string).

On the other hand, I'd like to have a way to keep nominal typing and lightweight type syntax for variants. Here is what I ended up moving to:

constFoo:unique symbol=Symbol("Foo");constBar:unique symbol=Symbol("Bar");constMyEnum={  Foo,  Bar,}asconst;typeMyEnum=typeofMyEnum[keyoftypeofMyEnum];declarenamespaceMyEnum{typeFoo=typeofMyEnum.Foo;typeBar=typeofMyEnum.Bar;}export{MyEnum};

This usesunique symbol for nominal typing, which requires either astatic readonly class property or a simpleconst. Using a class prevents you from usingMyEnum as the union of all variant values, so constants must be used. I then combine it with a type namespace to provide type-level support forMyEnum.Foo.

Obviously, this approach is even more inconvenient at the implementation side, but I find it more convenient on the consumer side. The implementer side complexity is less relevant if using codegen.Symbol is also skipped inJSON.stringify for both keys and values, so if you rely on it then it won't work and you'd need a branded primitive type if you care about nominal typing. I use schema-guided serialization so it's not an issue for me, but it's worth mentioning.

The "record of symbols" approach addressesthe complaints in this blog post about support variant annotations such as@deprecated: you can annotate in the namespace, or the symbol values.

I hope this message helps others when evaluating available solutions when migrating away from TSenums.

RyanCavanaugh and pspeter3 reacted with thumbs up emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@DanielRosenwasserDanielRosenwasserDanielRosenwasser left review comments

@jakebaileyjakebaileyjakebailey approved these changes

Assignees

@RyanCavanaughRyanCavanaugh

Labels
Author: TeamFor Uncommitted BugPR for untriaged, rejected, closed or missing bug
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

10 participants
@RyanCavanaugh@typescript-bot@jakebailey@scottmas@ptts@robpalme@mohsen1@rauschma@demurgos@DanielRosenwasser

[8]ページ先頭

©2009-2025 Movatter.jp