-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
Error when using TypeScript classes that depend on each other #10712
Comments
That's not an issue with TypeScript. Seems like you are using requirejs so read this: http://requirejs.org/docs/api.html#circular |
OK, thanks for the response! The design is fine: while in a few simple cases where this happens it might be possible to isolate some parts into a separate common file, in other cases, the 2 (or more) classes really need to work together and be able to access functionality/properties of each other. I tried removing the import MainClass = require("MainClass");
let main = new MainClass.MainClass(); or import ClassA = require("ClassA");
import ClassB = require("ClassB");
export class MainClass
{
constructor()
{
console.log("Logs from MainClass:");
console.log("ClassA parameter name = " + ClassA.ClassA.ParameterNames.SomeName);
console.log("ClassB parameter name = " + ClassB.ClassB.ParameterNames.SomeName);
let objectA = new ClassA.ClassA();
let objectB = new ClassB.ClassB();
objectA.doAction();
objectB.doAction(); // exception in here
}
} which is terrible (especially if you have to do that throughout your whole codebase). |
That would make it so TypeScript has to predict how the modules will be loaded and the capabilities of the module loader. Cross module circular references are really complex (and are largely considered bad design practice) and each module loader has different levels of support and resolution logic for such things. You are also conflating circular references with "old" TypeScript module import syntax and the better supported ES2015/ES6 syntax. For example, you should use: import { MainClass } from "MainClass";
let main = new MainClass(); If the main thing exported from export default class MainClass {
/* class here */
} and then when you want to import it: import MainClass from "MainClass";
let main = new MainClass(); And then when TypeScript emits to AMD, it will resolve all those names for you, and makes transition to ES2015 modules easier in the future. Nothing "ugly" about that. |
Thanks @kitsonk ! I had tried |
In a medium-sized project (single page web app client), we are running into a blocking issue with TypeScript when two classes depend on each other.
I have created a very simple minimal example to demonstrate the problem: see the code below, or download the fully self-contained code (with VS2015 project) here:
https://bitbucket.org/KoenT_IM/typescripttests/src/93e810457a5d1cf9286ea17cfe2a0ef6595070ec/Applications/MutualDependenciesTest/?at=master
TypeScript Version: 1.8.36.0
Code
ClassA.ts
ClassB.ts
MainClass.ts
app.ts
index.html
Expected behavior:
Actual behavior:
The project/code builds without any errors/warnings, but at runtime, execution fails.
What happens is that in the ClassB.doAction() call, ClassA is an "empty object", and ClassA.ParameterNames is undefined.
So, from a developer point of view: doing
import ClassA = require("ClassA");
in MainClass.ts lets you useClassA.ParameterNames.SomeName
as expected, whereas doing that exact same import in another TypeScript file (ClassB.ts) and using the exact same codeClassA.ParameterNames.SomeName
compiles but fails at runtime.The text was updated successfully, but these errors were encountered: