Question presented to candidate:
"In our TypeScript Vue app, inject('cart') comes back as unknown, so people cast it with as Cart and we have had runtime crashes when the provider was missing. How do you make provide and inject type-safe end to end?"
What a strong answer should cover:
- Use a
Symbolkey typed asInjectionKey<T>, exported from one module, soprovide(key, value)checks the value andinject(key)returnsT | undefinedinstead ofunknown. injectis honestly typedT | undefinedbecause a provider may be missing; handle it with a default (inject(key, fallback)returnsT) or auseX()helper that throws a clear error.- String keys with a generic,
inject<Cart>('cart'), and non-null assertions are only promises to the compiler, not checks. - A reusable
createContext<T>()factory that returns a typed provide/use pair and hides the key. - Provide readonly state plus typed action functions, so the type also documents who may mutate.
- Verify with
vue-tsc, since templates and<script setup>are only checked by it, not by plaintsc.
Clarifying questions expected:
- "Is there always a provider above every consumer, or are some consumers optional?"
- "Is this application code or a library other teams consume?"
Code / implementation expected: Yes β an InjectionKey<T>, a typed provide, and a useX() helper (or a generic factory) that throws when the provider is missing.