Skip to content

Design Meeting Notes, 12/7/2022 #51813

Closed
Closed
@DanielRosenwasser

Description

@DanielRosenwasser

extends as an Array in tsconfig.json

#29118

  • Today, if you want to compose tsconfig.jsons, you have to have them extend linearly, know about each outer.
  • This PR makes it so you can write `"extends": ["a", "b", "c"]
    • Makes it appear as if b extends a, and c extends b.
  • What about conflicts?
    • Last in wins.
    • So no error?
      • That's the behavior today.
  • There's sort of a difference between these things extending versus specifying the overrides inline.
  • Most analogous thing here is object spread ({ ...a, ...b, ...c, /* inline options */ }).
    • These don't merge/compose, they just override.
  • Just make sure we document these gotchas.

isolatedModules on Global/Script Files

#46295
#51479

  • Working on verbatimModuleSyntax, we realized it's a subset(?)/superset(?) of isolatedModules
  • One rule of isolatedModules: every file needs to be a module.
    • Why? Want to avoid issues with cross-file declaration merging.
      • Compilers that can't resolve across files cannot do implicit name resolution from things like namespaces.
  • Maybe instead of isolatedModules expecting only modules, we disallow certain kinds of declarations like namespaces in the global scope.
    • enums have the same issue.
  • [[Far-off discussion around our behavior when --isolatedModules is enabled]].
  • What are the use-cases?
    • Need one script that needs to be included.
    • Electron sandboxing needs a pre-sandbox script.
  • Did these people really just want moduleDetection: force?
    • No, not necessarily.
  • So
    • enums

    • namespaces

    • decorator metadata (already banned in isolatedModules)

    • static block in a class that merges with a namespace???

      namespace N {
          export const x = 0;
      }
      
      class N {
          static {
              x; // not resolved - phew! 😅
          }
      }
      • Validated - not an issue.
  • We are looking at this because verbatimModuleSyntax (Proposal: deprecate importsNotUsedAsValues and preserveValueImports in favor of single flag #51479) should be a superset.
    • Yes, superset - all of the rules of isolatedModules and some extra stuff.
  • Again, weird that both of these say "modules" but now also affect global scope.
    • Probably Fine?

Deprecating the module Keyword From Namespace Declarations

https://github.com/tc39/proposal-module-expressions
https://github.com/tc39/proposal-module-declarations

  • TypeScript supports the module keyword for namespaces (from when they were originally called "internal modules").

    module foo {
      // ...
    }
    
    // is equivalent to
    
    namespace foo {
      // ...
    }
    • It was confusing always clarifying "internal module" vs "external module", so we introduced the namespace keyword back in TS 1.5 (Namespace keyword #2159). Intent was to phase out usage of module outside of declare module "...".
  • Now TC39 has two proposals that want to use the module keyword.

    • The module expressions proposal don't have any conflict, but are confusing if TypeScript's namespaces can still use module.
    • The module declarations proposal creates a conflict.
  • We don't necessarily want the module declaration proposal, but it does raise the question: what do we want for the module long-term? We want to ask this question regardless of these proposals.

  • Do we want to deprecate or remove support for the module keyword when used for namespaces?

  • Feels like it's time to retire the module keyword for these - but geez there's a lot of code that already uses the module keyword for namespaces when we do a casual code search.

    • Well a lot of these search hits are TypeScript itself, tests for supporting TypeScript (e.g. in Prettier), or really old code whose status we can't really evaluate.
  • Coming back to the proposal - it would be bad if module started to mean a new thing. If you look at a TypeScript file, you won't know if the syntax refers to a TypeScript "internal module"/namespace, or if it refers to the new ECMAScript thing.

    • We have reservations regarding that (plus questions about the cost/benefit of this feature).
    • Really don't want to spend time on the semantics of the proposal though.
  • So what's deprecation vs. removal imply?

    • Deprecation means we have until 5.5 to remove, but users can use deprecation opt-out.
    • Removal means that we would...still gracefully parse, but give an error. Then one day make it mean something else if module expression/declarations ever proceeded to ECMAScript.
  • We feel okay about deprecation. Deprecation means we have a pretty good window of opportunity to change our mind. It also allows people to get the signal "hey, stop using the module keyword for namespaces".

    • Plus we could have quick fixes and it's easy enough to write a find/replace regex.

      Find:

      (\s*(?:declare )?)module (\w+(?:\.\w+)*\s*\{)
      

      Replace:

      $1namespace $2
      

      or

      \1namespace \2

      • Probably covers 99% of code, the rest is manually correctable.
  • [[EDITOR'S NOTE]]: we are not talking about deprecating module used like this:

    // This is fine!
    module "foo" { // <- notice the quotes!
    // ...
    }

    We are talking about deprecating module used like this

    module foo { // <- notice this is just an identifier
    // ...
    }

    in which any existing code would need to be rewritten to use namespace.

    // This is fine!
    namespace foo {
    // ...
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @DanielRosenwasser@RyanCavanaugh

        Issue actions

          Design Meeting Notes, 12/7/2022 · Issue #51813 · microsoft/TypeScript