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

Support merging classes and modules across files #3802

Closed
dbeckwith opened this issue Jul 10, 2015 · 14 comments
Closed

Support merging classes and modules across files #3802

dbeckwith opened this issue Jul 10, 2015 · 14 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@dbeckwith
Copy link

I currently have a setup something like this:
A.ts

module mod {
  export class A {
  }
}

B.ts

/// <reference path="A.ts" />
module mod.A {
  export class B extends A {
  }
}

But I'm getting the error in B.ts:
A module declaration cannot be in a different file from a class or function with which it is merged.
It works fine, however, if the declarations are in the same file: Playground

In my compiler options, I'm concatenating all the files together in the output, so shouldn't it not matter that they're in different source files? Even if the output wasn't concatenated, I don't understand how the declarations being in separate files changes anything.
Basically, the structure I'm going for is that A is going to have a lot of subclasses, and I wanted to have them all be in a module also called A. It just makes sense organizationally to me.

Why is this not allowed? Is there a way around it?

@RyanCavanaugh
Copy link
Member

It isn't allowed because we can't be sure about the ordering of the files. A.ts must execute first; this is different from other module merging scenarios because those can generally take place in any order.

@dbeckwith
Copy link
Author

But if I'm compiling with concatenated output, can't you guarantee the order of execution?

@danquirk
Copy link
Member

There are simple cases the compiler could know it's safe (but doesn't today), and more complex cases that would be harder (if not impossible) to analyze correctly. We generally haven't yet seriously invested in features that require analyzing ordering (whether code within a file, or file ordering itself), especially if that investment would still only cover some of the relevant scenarios (ex only allow classes and modules to merge in specific ordering and with --out). And of course there's another alternative where we don't give an error at all and leave it up to the user to make sure the ordering is working correctly/as intended. I'll edit the title a bit to reflect the suggestion.

@danquirk danquirk changed the title Why can't a module merge with a class from a different file? Support merging classes and modules across files Jul 10, 2015
@danquirk danquirk added Suggestion An idea for TypeScript Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Jul 10, 2015
@dbeckwith
Copy link
Author

Okay, I understand, and I see the potential difficulty of the general problem. I can adjust my model to work around this, but if in the future support is built for module/class/function dependency ordering that would be great.

@indus
Copy link

indus commented Jul 21, 2015

I need this, too.

@mhegazy mhegazy added In Discussion Not yet reached consensus and removed Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Feb 22, 2016
@niabot
Copy link

niabot commented Mar 30, 2016

I also would like to have this feature. For readability i hold a lot of classes in separate files, which will be compiled into many tiny modules, which i don't need.

The example project structure (the source directory as root):

rootDir
|--libDir
|  |--packageDir1
|  |  |--ClassA.ts
|  |  +--ClassB.ts
|  |--packageDir2
|  |  |--ClassC.ts
|  |  +--ClassD.ts
|  |--packageDir1.ts
|  +--packageDir2.ts
+--lib.ts

The example content of lib.ts is:

import * as package1 from './libDir/packageDir1.ts'; export {package1};
import * as package2 from './libDir/packageDir2.ts'; export {package2};

On the other hand packageDir1.ts contains:

import {ClassA} from './packageDir1/ClassA';
import {ClassB} from './packageDir1/ClassB'; 

The final Library is used like this:

import * as lib from 'lib';
import ClassA = lib.package1.ClassA;
var instance = new ClassA();
var instance2 = new lib.package2.ClassC;

This works fine as it is if compiled with '--outFile', but it introduces a lot of not needed modules like 'lib/package1' and 'lib/package1/ClassA'. Additionally it increases the likelihood of cyclic references which can make class inheritance fail and enforces careful ordering of imports.

I really would like to see the compiler to recognize such a structure and to transform it from something similar to this:

module lib {
  export module package1 {
    export class ClassA {
      ...
    }
    export class ClassB {
      ...
    }
  }
}

to this:

module lib {
  class ClassA { ... }
  class ClassB { ... }
  class ClassC { ... }
  class ClassD extends ClassB { ... }
  export var package1 = {
    ClassA: ClassA;
    ClassB: ClassB;
  }
}

@dev-mraj
Copy link

dev-mraj commented Nov 8, 2016

+1

i'd like to have this, to just es6 output with typescript so then i can use clousercompiler to optimize that for es5

@salim7
Copy link

salim7 commented Oct 9, 2017

We would need this feature as well.

@deinok
Copy link

deinok commented Oct 24, 2017

On "module":"es2015" and "target":"es3"
We should only require to delete the export { MyClass }; an the files would be ready to concat following the order of the imports and if something have been already imported, dont concat them

@RyanCavanaugh RyanCavanaugh added Good First Issue Well scoped, documented and has the green light Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Oct 30, 2017
@RyanCavanaugh RyanCavanaugh added this to the Community milestone Oct 30, 2017
@RyanCavanaugh
Copy link
Member

Accepting PRs for this - just re-use the existing logic we have for detecting if two constructs will be in the right order in an outFile

@deinok
Copy link

deinok commented Oct 31, 2017

@RyanCavanaugh Should I writte a proposal of how this should work before send the PR?
With this feature we should be able to avoid WebPack, babel, rollup and others for the only task to use ES2015 imports while targeting ES3 or ES5

@RyanCavanaugh
Copy link
Member

There shouldn't be anything to propose other than "correctly don't issue the error when the code would work". The emit should be the same; if you think it should be something different then we should get on the same page about what the scenario is

@RyanCavanaugh RyanCavanaugh modified the milestones: Community, Backlog Mar 7, 2019
@terrible-coder
Copy link

I kinda need this feature too. Any recent updates?
Also, what would the import statements look like for importing these "distributed" class/namespace declarations?

@RyanCavanaugh RyanCavanaugh added Declined The issue was declined as something which matches the TypeScript vision and removed Help Wanted You can do this Good First Issue Well scoped, documented and has the green light labels Mar 1, 2024
@RyanCavanaugh RyanCavanaugh removed this from the Backlog milestone Mar 1, 2024
@RyanCavanaugh
Copy link
Member

Non-module compilation is basically extinct at this point, and no one has bothered implementing this since the seven years since it was approved, so let's just not bother at this point.

@RyanCavanaugh RyanCavanaugh closed this as not planned Won't fix, can't repro, duplicate, stale Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

10 participants