Start here. This is the direct spoken answer to practice first.
Overview
TypeScript interfaces disappear at runtime, so Angular needs a real runtime token to resolve non-class dependencies.
I use an InjectionToken for configuration, functions, interface-shaped abstractions, or other values that do not have a class token at runtime. useValue supplies an existing value, useFactory computes one, useClass asks Angular to create the specified class, and useExisting aliases another provider. The token object itself is the identity; its description string is only for debugging.