Closed liplum closed 1 year ago
After I checked the source code, I found the factory checking in Container.get
.
get<T, U extends Array<unknown> = never>(
token: Token<T, U> | MaybeToken<T>,
tags: symbol[] | symbol = [],
target?: unknown,
injectedArgs: Array<unknown> = [],
): T {
const item = <Item<T> | undefined>this._registry.get(getType(token));
if (item === undefined || item.injected === undefined) throw `nothing bound to ${stringifyToken(token)}`;
const value = isFactory(item.injected)
? !item.singleton
? item.injected(...injectedArgs)
: (item.cache = item.cache || item.injected())
: item.injected;
const tagsArr = valueOrArrayToArray(tags);
if (tagsArr.indexOf(NOPLUGINS) === -1)
item.plugins.concat(this._plugins).forEach((plugin) => {
plugin(value, target, tagsArr, token, this);
});
return value;
}
the isFactory
only checks whether the injected
is a function no matter it comes from toValue
or toFactory
.
const isFactory = <T>(i: Injected<T>): i is Factory<T> => typeof i === "function";
@liplum i published a new version (2.0.0-alpha.7). That should fix the bug.
Yes, it works.
Describe the bug The Container.bind(...).toValue(...) consider the a given function as a fatory.
To Reproduce
the console output is
Expected behavior I want to bind a Getter function, such as (options) => create(options) with
toValue
, however, the container considered it as a factory and tried to call it and retrieved the return value.I don't think
toValue()
should detect its type under the hood, which made me confused. Instead,toFactory()
is more suitable for this.Environment (please complete the following information):
Additional context The workaround is to wrap the function with a new function.
But it makes the typing sucks in typescript. Because the token should be
token<()=>(text:string)=>void>("MyType")
, then the return value fromcontainer.get(...)
is typed by()=>(text:string)=>void
but(text:string)=>void
is actually expected.