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

Design Meeting Notes, 10/14/2022 #51309

Closed
DanielRosenwasser opened this issue Oct 25, 2022 · 0 comments
Closed

Design Meeting Notes, 10/14/2022 #51309

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

Comments

@DanielRosenwasser
Copy link
Member

Enums

#50528

  • Background: two types of enums

    • "modern enums" - enums represent a named union of well-known enum literal types
    • "numeric enums" - these are squishy and are mostly compatible with number
  • What makes an enum numeric?

    • Some intermediate computations (e.g. FlagA | FlagB)
    • But when we do declaration emit, we inline the computed values of these.
      • Which makes them non-numeric enums (i.e. they become modern literal enums!)
  • What if we just tried to make everything a literal enum?

    • Trivially computable enum members get a literal subtype.
    • Non-computable enum members get a unique subtype of number.
    enum E {
        A = 1,            // E.A = [E#1] (TypeFlags.NumericLiteral | TypeFlags.EnumLiteral)
        B = 1,            // E.B = [E#1] (TypeFlags.NumericLiteral | TypeFlags.EnumLiteral)
        C = 1,            // E.C = [E#2] (TypeFlags.NumericLiteral | TypeFlags.EnumLiteral)
        D = "foo",        // E.D = [E@"foo"] (TypeFlags.StringLiteral | TypeFlags.EnumLiteral)
        E = B + C,        // E.E = [E#3] (TypeFlags.NumericLiteral | TypeFlags.EnumLiteral)
        F = someFunc(1),  // E.F = unique E (TypeFlags.Enum)
        G = someFunc(1),  // E.G = unique E (TypeFlags.Enum)
    }
  • Bitflags? How do you assign back?

    • We still preserve the "squishy number" behavior.
  • What about narrowing on unique values?
    *

  • What gets broken in the compiler?

    • Incorrectly optimistic narrowing (i.e. Trade-offs in Control Flow Analysis #9998)
    • Comparison of FlowType against 0.
      • Correct error.
      • But we allow assignment of a numeric literal to an enum.
        • So flowType.flags === 0 fails, but flowType.flags = 0 works?
        • Strange - first time comparability is stricter than assignability.
          • If you can assign it, you should be able to check if it's there.
    • Check on CheckMode being truthy and then not-assignable to 0
      • Correct error.
  • Maybe there's room here for something like leveraging "freshness" the same way we do for object literal freshness in excess property checking.

  • Declaration file says that E.F and E.G have no initializer - not auto-numbered, just computed.

  • Seems like we're using flags quite a bit - if we're not broken terribly, that's a good indication that we can roll out the change.

  • The breakage isn't so much the concern - it's more the type-checking speed.

  • The fact that declaration emit has silently converted numeric enums to literal enums and nobody has run into issues is pretty telling.

  • Maybe there should not be a distinction around numbers vs strings - we can always have arbitrary unique objects as values.

    • Not necessarily something we want to go for just yet.
    • Plus, don't want to widen enums given enums proposal.
  • What's the emit? One-way bindings from name to value? Or do we do the reverse mapping?

    • We're doing two-way binding for the computed values.
      • So it's syntax directed, right? What happens if someFunc returned a string?
        • You'd get an error, we would still do a two-way binding.
      • Well, it really depends on the constant evaluator.

Declaration Files for Non-JS Files

#50133

  • We have no way to specify the shape of an imports from a .css, .wasm, etc. files.
  • Idea is to allow declaration files for these, using a different naming scheme than just .d.ts.
    • filename.d.ext.ts would imply the existence of a filename.ext
    • e.g.
      • styles.css would need a declaration file called styles.d.css.ts
  • What's the workflow here? Generate the declaration files ahead of time?
    • Similar to how people generate types from GraphQL queries and the like.
    • Seems like a reasonable workflow.
  • How should we surface this?
    • Boolean? "allowNonJsImports": true
    • List? "allownonJsImports": ["css", "html"]
  • Argument in favor of lists - avoid possible misconfiguration issue.
    • But wouldn't grab those .d.ext.ts files unless they're there and imported in the first place.
  • What does the declaration emit look like for a .json file?
    • We technically have supported but disabled JSON file declaration emit for a while.
  • Does the boolean control JSON imports?
    • We already have a flag (resolveJsonModules)
    • Probably the new flag should imply the resolveJsonModules
  • Is this a breaking change for people doing .json imports?
    • Not for Node ESM users?
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Oct 25, 2022
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