Skip to content

Design Meeting Notes, 10/20/2023 #56164

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

Closed
DanielRosenwasser opened this issue Oct 20, 2023 · 0 comments
Closed

Design Meeting Notes, 10/20/2023 #56164

DanielRosenwasser opened this issue Oct 20, 2023 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

isolatedModules and Cross-File Enum Member References

#56153

  • "Who doesn't love enums?"

  • If you have a numeric enum member in one file, and a numberic enum that references that first one in another file...

  • ...and a subsequent member has no initializer...

    // foo.ts
    enum Foo {
        A = 123,
    }
    
    // bar.ts
    import { Foo } from "./foo";
    
    enum Bar {
        B = Foo.A,
        C
    }
    import { Foo } from "./foo";
    export var Bar;
    (function (Bar) {
        Bar[Bar["B"] = 10] = "B";
        Bar[Bar["C"] = 11] = "C";
    })(Bar || (Bar = {}));
  • ...under isolatedModules we don't issue an error - we don't know what this is supposed to be.

  • We do when A is a string - and if it is, we generate a void 0 for the initializer - but not if it's numeric (as above).

    // foo.ts
    enum Foo {
        A = "hello",
    }
    
    // bar.ts
    import { Foo } from "./foo";
    
    enum Bar {
        B = Foo.A,
        C
    }
    import { Foo } from "./foo";
    export var Bar;
    (function (Bar) {
        Bar["B"] = "10";
        Bar[Bar["C"] = void 0] = "C";
    })(Bar || (Bar = {}));
  • Should we?

  • Probably?

  • A compiler doesn't know what it should perform - numbers get a reverse-map, strings don't.

    • Well, a compiler doesn't, but runtime emit can do a dynamic check.
      • Doing a lot of those is undesirable.
      • You only have to do one, right?
      • No, each uninitialized enum member may have to perform the same check.
        • (Is this true?)
  • Some philosophical discussion - should isolatedModules imply this dynamic behavior.

    • We won't emit these things, so how are compilers supposed to know what they should do?
    • On the other hand, there is nothing preventing compilers from making these enums "work".
  • We have a few choices.

    1. Force people to do the auto-numbering themselves.

      // bar.ts
      import { Foo } from "./foo";
      
      enum Bar {
          B = Foo.A,
          C = B + 1
      }
    2. Emit a dynamic check using typeof.

    3. Make a rule - enum members referencing another external enum must always be numeric, or explicitly converted to a string. Otherwise, it is an error. And under `isolatedModules``, we will have to assume nothing about the value of the enum member itself.

      • So we will assume B is a number, and use numeric reverse-mapping emit - but C will need an explicit initializer.
  • Conclusion: we are leaning towards the last-mentioned rule

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

2 participants