3

I'm using dependency injection with typescript, means that I can create an object in a module without importing the class (I'm importing an Injector instead which gives me the object instance I need). If I now want to provide a type for the receiving variable, I get a Unresolved type error. Any good solution for that?

Example

An object of type 'MainHelper' is returned by Injector.injectMainHelper(); but the type is unknown to the current module, because I haven't imported MainHelper (and I don't want to import it).

let mainHelper:MainHelper = Injector.injectMainHelper();

You can check the full code here.

5
  • Which IoC container are you using? Angular 2? Commented May 30, 2016 at 14:49
  • No, I just tried DIY DI for fun. So no container or framework. Commented May 30, 2016 at 14:51
  • I've been working on a container for some time now you can check it out at github.com/inversify/InversifyJS also I recommend you to read blog.wolksoftware.com/… point two explains the problem that you are having here and why interfaces are needed. Commented May 30, 2016 at 14:54
  • @OweRReLoaDeD Thanks. I already tried inversify, in my opinion it's too much magic. Don't get me wrong, I don't want to say it's bad, it's just adding another layer of complexity. Thanks for pointing me to the blog, I'll check it out. I guess everything will boil down to use interfaces everywhere. Commented May 30, 2016 at 14:56
  • No problem! you are doing the right thing, is not good to "use magic" if you don't fully know what's going on. Commented May 30, 2016 at 14:58

1 Answer 1

2

How about declaring interfaces?

interfaces.d.ts

interface IMainHelper {
    //... 
}

main_helper.ts

class MainHelper implements IMainHelper {
    //... 
}

other_file.ts

/// <reference path="./interfaces.d.ts" />

import Injector from "./injector";

let mainHelper: IMainHelper = Injector.injectMainHelper();

Note: If you add the reference to your tsconfig.json you won't need to add it in the file.

Update

I just tried and if you have two files:

test1.ts

class MainHelper {

}

var Injector = {
    injectMainHelper: function() {
        return new MainHelper();
    }
}

export default Injector;

test2.ts

import Injector from "./test1";

let mainHelper = Injector.injectMainHelper(); // mainHelper is MainHelper

TypeScript is able to infer the type of mainHelper. If you don't add the type the compiler will automatically detect its type.

If you have something more generic like:

var Injector = {
    injectSomething: function(somethingID) {
        // find something and dependencies
        return new Something(..dependencies);
    }
}

The solution would be to use generics:

let mainHelper = Injector.injectSomething<MainHelper>("mainHelperID");

But in that case you will need interfaces once more...

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer. Can you please add the definition file?
The definition file is interfaces.d.ts
Foo, I'm sorry.... worked 8 hours today, my brain is mud... :). Ok, this also would help with not depending upon concretes, but abstractions. I'll incorporate it into my project and report back. Thanks.
Worked. Thank you very much.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.