Adding some clarity to @GünterZöchbauer's response.
When dealing with tokens, useExistingOrThrowIfThereIsNone is the correct term. useExisting simply creates an alias for another token, not an instance. Therefore, there must be a token referenced by useExisting, or else an exception will be thrown. However, when it comes to instances, it will function as long as the last token in the chain registers an instance, making it effectively useExistingOrCreateIfThereIsNone.
For example:
// T = token, I = instance
providers: [
{provide: B, useClass: A}, // T[B] => I[A]
{provide: C, useExisting: A}] // T[C] => ??? - there's no T[A] declared
...
constructor(private a: B) {} // works
...
constructor(private a: C) {} // throws an exception:
In this scenario, the second declaration will throw an error because token C refers to token A, which is not declared anywhere, even if there is an instance of class A in the injector. Angular will not automatically create an instance A for token C or associate token C with an existing instance A. This was accidentally discovered in one of my projects. :)
The following example will work due to the reasons explained in other responses:
providers: [
{provide: B, useClass: A}, // T[B] => I[A]
{provide: C, useExisting: B}] // T[C] => T[B] => I[A]
...
constructor(private a: B) {} // works
...
constructor(private a: C) {} // works
In this case, an instance of A will be created for token C, even if no instance of A was previously created for token B. Therefore, for token C, it means "use whatever instance should be provided for token B", and for token B, it means "use existing instance A or create new if none exists".