Skip to content

Proposal for module / namespace behavior to allow class-per-file development approach #15827

Closed
@fis-cz

Description

@fis-cz

This is related to #447 but it seems nobody is reading it anymore.

From my perspective, the typescript compiler should do combine same namespaces to the same IIFE, even if its splitted over multiple files. Otherwise its not the same namespace. And its confusing as in real, the 'namespace' keyword is not TypeScript namespace, but JavaScript namespace. Moreover, same named modules splitted over multiple files should be also combined to single output js file to be possible to split AMD, CommonJS or SystemJS module to mutiple files.

I know you are trying to keep as close as possible to ES spec and there is no such possibility to split anything over multiple files but it will be really helpful.

Consider we have a project with the following folder structure:

program
   a
      Ns_a1
         ClassA.ts
         ClassB.ts
      Ns_a1.Ns_a12
         ClassA.ts
      module_exports.ts
   b
      Ns_b1
         tools.ts
      module_exports.ts
   blah.ts
   tsconfig.json

a and b are modules, Ns are namespaces. Export file (module_exports.ts) should be possible to be used as is should be simply possible to define and find out what we are exporting out of the module without need of looking to all files in the module folder structure. Of course, export/reexport of the class, function, namespace or whatever else should be possible from any file in the same module scope, but will be messy in big projects.

The compilation output should be a.js , b.js and blah.js according to definition in files:

module_exports.ts

module a {
   // reexport interface and class B form namespace Ns_a1
   export Ns_a1.I;
   export Ns_a1.B;

   // export whatever else from the module
   export function something() {
   }

   export const blah: string = "blah";

   // of course, it should be possible to export the whole namespace
   export Ns_a1;
}

ClassA.ts:

module a {
   namespace Ns_a1 {
      /* partial */ class A { 
         // class code here, class is not exported so not visible out of Ns_a1
         // for partial proposal see ClassB.ts
      }
   }
}

ClassB.ts:

module a {
   namespace Ns_a1 {

      /* partial */ class A {
         // class merge or Duplicate identifier error
         // I would recommend considering of adopting the "partial" keyword from C#
         // if it would be specified, merge, if not, Duplicate identifier error
      }

      // under normal circumstances, i would place I to separate file but just to shorten the post
      export interface I {
         // exported interface so visible inside module a
      }

      export class B extends A implements I {
         // class code here, class is exported so visible as Ns_a1 inside module a
      }
   }
}

tools.ts

// tools does not define module so nothing to be merged with and works as in the current TS, so
// compiled to separate file (or considered as separate file in case of --out)
namespace Ns_a1 {
   // can't be merged as tools.js is separate module by nature (as it works now)
}

I will not write the code for the b folder branch as it is hopefully clear from previously mentioned code.

Please note the module keyword is supposed to be a AMD, UMD, CommonJS or SystemJS module, not a module pattern from Javascript.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions