I would like to extend the functionality of some classes.
For example, I would like to automatically create a child from a container.
Normally I would do something like this:
import { Container } from 'inversify';
Container.prototype.createChild = () => {
const child = new Container();
child.parent = this;
return child;
};
declare module 'inversify' {
interface Container {
createChild: Container;
}
}
This is not working:
node_modules/inversify/dts/inversify.d.ts(1,10): error TS2484: Export declaration conflicts with exported declaration of 'Container'
server/src/modules/prj/core/di.ts(3,1): error TS2304: Cannot find name 'Container'.
server/src/modules/prj/core/di.ts(4,21): error TS2304: Cannot find name 'Container'.
I guess something is special in the way the d.ts files are created since it is easily possible in rxjs
See this sample
Can you please try class based inheritance:
interface CustomContainer extends interfaces.Container {
createChild: Container;
}
class CustomContainer extends Container {
createChild = () => {
const child = new Container();
child.parent = this;
return child;
}
}
I have't try this but I assume that it will work. Please let me know if it solves your problem :wink:
Thank you for the quick response, great work btw!!!
Inheriting will work, but it doesn't fit my use case (lib) it's more for local use.
If I go that path I will have to force user's of my lib to use my Container version, which is a bad idea.
I'm also not a fan of monkey patching but if it's harmless I can live with it.
Patching the prototype while extending the type the way I tried to is the official way to do it as described in the TypeScript docs here (see Module Augmentation)
I think the reason it's not working is due to the use of default exports.
Also the main file is renaming (as) all the defaults which might also be a problem.
I also tried:
declare module 'inversify/dts/container/container' {
interface Container {
createChild(): Container;
}
}
With no luck, there is no Container interface in the module since the module is the Container (default)
I believe default is not a good pattern, RXJS doesn't use it, angular 2 does not as well and they are 2 leading TypeScript projects...
It doesn't save much anyway...
BTW, creating a child from the parent directly is a good addition, that helper function makes sense a parent creating a child...
Interesting :thinking: do you know about any issue/link in which I can learn more about the default exports issues? I want to learn more before I introduce a change.
I will introduce Container.prototype.createChild as a feature. I have create #408 to track it. Feel free to send a PR.
Well, Axel Rauschmayer from the @2ality blog commented about it, he's someone to listen to...
You can also read a very good explanation here
I don't see any good reasons to use default exports, it doesn't give anything really, saves nothing.
You can also see that my attempt to augment the module failed and it shouldn't, I did it "by the books"
Also: basarat gitbooks
@lholznagel thanks.
There are more reasons that devs didn't find yet, I think this issue is on more reason... I'm 99% sure its due to default exports.
I would ban them personally :)
@shlomiassaf @lholznagel thanks a lot for the links!
I have created another issue to remove the default exports #410 I'm closing this issue because now we can use #408 & #410 to track the required actions.
@shlomiassaf thanks a lot for trying the beta and sharing feedback it is a really valuable contribution :+1: