Appearance
Interview drills
Short prompts you can answer out loud. Try each before opening the answer - no peeking. 😉
1. unknown vs any
Prompt: When would you type res.json() as unknown instead of casting straight to Product?
Answer
When the payload is untrusted or unstable. unknown forces a type guard or validator before property access. A direct cast (as Product) is an unchecked assumption - fine for trusted internal APIs in prototypes, risky for public APIs.
2. Discriminated union for UI state
Prompt: Model and render loading / success / error for a user profile fetch.
Answer
ts
type Profile = { name: string }
type ProfileState =
| { status: 'loading' }
| { status: 'success'; profile: Profile }
| { status: 'error'; message: string }
function label(state: ProfileState): string {
switch (state.status) {
case 'loading':
return 'Loading'
case 'success':
return state.profile.name
case 'error':
return state.message
}
}3. Fix the generic
Prompt: What is wrong, and how do you fix it?
ts
function getById(items: { id: string }[], id: string) {
return items.find((i) => i.id === id)
}
// Caller loses specific item fields (title, etc.)Answer
ts
function getById<T extends { id: string }>(items: T[], id: string): T | undefined {
return items.find((i) => i.id === id)
}The generic preserves the element type instead of widening to { id: string }.
4. Utility types for PATCH
Prompt: Given type Task = { id: string; title: string; done: boolean }, type a PATCH body that cannot change id and may send any subset of the other fields.
Answer
ts
type TaskPatch = Partial<Omit<Task, 'id'>>5. Narrow this error
Prompt: Type catch (err) and safely read a message.
Answer
ts
catch (err: unknown) {
const message = err instanceof Error ? err.message : String(err)
}Don't type err as any or Error blindly - non-Error throws exist.
6. Interface vs type
Prompt: Model Clickable | SubmitButton where one has href and the other has type: 'submit'. Interface or type?
Answer
Use a type union (often with a discriminant like kind). Interfaces alone cannot express alternate shapes as a union.
7. void callbacks
Prompt: Why type onClose: () => void instead of () => undefined?
Answer
void means callers should ignore the return value. It also allows passing functions that return something (common with inline handlers). () => undefined requires returning undefined specifically.
8. Explain Awaited<ReturnType<typeof load>>
Prompt: What does this extract?
ts
async function load() {
return { items: [] as string[] }
}
type X = Awaited<ReturnType<typeof load>>Answer
{ items: string[] } - the resolved value inside the Promise returned by load.
Where next?
Enjoy!