Injection Tokens
Explain why InjectionToken exists and how it enables injecting non-class values like config objects or primitives.
Angular's DI system normally uses a class itself as the lookup key for a provider (inject HttpClient, get an HttpClient instance), but TypeScript interfaces, type aliases, and plain values (strings, objects, functions) don't exist at runtime — they're erased during compilation — so there's no runtime identity to use as a DI lookup key for them. InjectionToken<T> solves this by creating a unique, runtime-existing object specifically to serve as that lookup key, while still carrying the type T for compile-time type safety wherever it's injected.
It's like a coat-check ticket stub for a coat that has no owner's name sewn into the lining — the stub itself (the token) is the only reliable way to retrieve the right coat later, since the coat alone carries no identifying information.