If you want more control over the injection process you can use the token injection. This lets you inject the value that you registered.
The di can't resolve automatically the primitive types, eg. string, number, interfaces... You must specify Token registration the value and use the @Inject decorator for that
classService {constructor(@Inject("serviceStr") privatereadonly value:string) { }publicsay() {return`${this.value}`; }}classClient {constructor( @Inject("clientStr") privatereadonly value:string, @Inject("service") privatereadonly service:Service// or @Inject<IService>(Service) ) { }publicsay() {return`I like ${this.value} and ${this.service.say()}`; }}asyncfunctionrun() {constcontainer=newContainer();container.register("clientStr","coffee");container.register("serviceStr","pizza");container.register("service", Service);container.register("client", Client);constservice=awaitcontainer.resolve<Client>("client"); // new Service('pizza');constservice2=awaitcontainer.resolveByType<Client>(Client); // new Client('coffee', new Service('pizza'));console.log(service.say()); // client says: I like pizza and coffeeconsole.log(service2.say()); // client says: I like pizza and coffee}run();