Boarding pass · TypeScript Intermediate
TypeScript · Intermediate interview
An AI mock interview for developers comfortable with TypeScript basics. Go deeper into generics with constraints, the utility and mapped types, discriminated unions and type guards, and structural typing.
- Voice interview
- Live feedback
- Browser-only
- No installation required
Your report · sample
AI Readiness Score
Finish the mock and get this report — scored on content and English, with concrete tips and a model answer for every question, plus a study plan.
Your flight path
Five steps to interview-ready.
From a quick warm-up to a personalised study plan — here's the whole loop, and what you get at each gate.
Step 01
Preparation
Skim the topics and warm up — you're briefed before takeoff.
Step 02
AI Interview
A realistic AI interviewer asks tailored questions — answer by voice or text.
Step 03
Instant Score
Finish and get a 0–100 readiness score across content and English.
Step 04
AI Feedback
Concrete tips and a rewritten model answer for every response.
Step 05
Study Plan
A personalised plan targets your weakest areas — so the next run scores higher.
Preview the AI demo
See one answer scored, end to end.
The whole loop on sample data — question, your answer, instant feedback and a study plan. Hover to pause.
Interviewer · Question 1
“Tell me about yourself.”
Who it's for
- Developers using TypeScript daily
- Engineers who want to type tricky code well
- Anyone targeting mid-level TS-heavy roles
- Devs sharpening before interviews
What you'll practice
- Generic constraints and keyof/indexed access
- Utility types and writing mapped types
- Discriminated unions and type guards
- Structural typing and its gotchas
Topics covered
What this level expects.
Generics
- Constraints (extends)
- keyof & indexed access
- Default params
Utility & mapped
- Partial/Pick/Omit/Record
- Mapped types
- as const
Narrowing
- Discriminated unions
- Type predicates (is)
- Exhaustiveness
Structural typing
- Duck typing
- Excess property checks
- Assertions vs narrowing
Practice questions
12 questions, with model answers.
Read them, then run the live mock to answer out loud and get scored. Tap any question to reveal a model answer.
01How do generic constraints with extends work?Generics
A constraint restricts what a type parameter can be, so you can rely on certain properties inside the generic. <T extends { id: string }> means T can be any type that has an id string, letting you access x.id safely. Without the constraint the parameter is effectively unknown and you can't touch its members.
function byId<T extends { id: string }>(items: T[], id: string) {
return items.find(i => i.id === id);
}02What do keyof and indexed access types do?Generics
keyof T produces a union of T's property names, so keyof { a: 1; b: 2 } is 'a' | 'b'. An indexed access type T[K] gives the type of a property by key. Together they let you write functions that are type-safe over keys — like a getter that only accepts real keys and returns the matching value type.
function get<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}03What are default and inferred type parameters?Generics
A generic can have a default (<T = string>) used when the caller doesn't supply or the compiler can't infer one. Usually you let TypeScript infer type arguments from the values you pass, only specifying them explicitly when inference is impossible or you want to widen/narrow deliberately. Defaults are handy for flexible APIs where most callers want a common type.
04How do Partial, Pick, Omit, and Record work?Utility & mapped
They're built-in mapped types. Partial<T> makes all properties optional; Pick<T, K> keeps only the listed keys; Omit<T, K> removes the listed keys; Record<K, V> builds an object type with keys K and values V. They let you derive new types from existing ones instead of duplicating shapes — for example, an update DTO as Partial<User>.
05How would you write a mapped type yourself?Utility & mapped
A mapped type iterates over keys with [K in keyof T] and transforms each property's type. For example, a Readonly-like type adds the readonly modifier, and you can make properties optional or change their value type. This is the mechanism the built-in utilities are built on.
type Nullable<T> = { [K in keyof T]: T[K] | null };06What does 'as const' do?Utility & mapped
as const makes a literal deeply readonly and narrows it to its most specific literal types instead of widening — so { role: 'admin' } as const has role of type 'admin', not string, and arrays become readonly tuples. It's useful for config objects, action-type constants, and deriving union types from values with typeof.
const ROLES = ["admin", "user"] as const; type Role = typeof ROLES[number]; // "admin" | "user"
07What is a discriminated union and why is it useful?Narrowing
It's a union of object types that share a common literal 'tag' property (the discriminant). Switching on that tag lets TypeScript narrow to the exact member in each branch, so you get type-safe access to the fields specific to that case. It's the idiomatic way to model states, events, or results.
type Result = { ok: true; data: string } | { ok: false; error: string };
if (r.ok) r.data; else r.error;08What is a user-defined type guard?Narrowing
It's a function whose return type is a type predicate (arg is Type). When it returns true, TypeScript narrows the argument to that type in the calling branch. You use it to encapsulate a runtime check — like validating a shape — and teach the compiler about the result.
function isUser(x: unknown): x is User {
return !!x && typeof (x as User).id === "string";
}09How do you make a switch over a union exhaustive?Narrowing
Add a default branch that assigns the value to a never typed variable. If you later add a new union member and forget to handle it, the value won't be never and the compiler errors, forcing you to update the switch. It turns 'I forgot a case' into a compile-time failure.
default: { const _exhaustive: never = value; throw new Error(_exhaustive); }10What is structural typing and how does it differ from nominal typing?Structural typing
TypeScript types are compatible based on their shape, not their declared name — if an object has the required members, it's assignable, even if it was never declared as that type. Languages like Java are nominal: compatibility requires the explicit type/inheritance. Structural typing is flexible and matches how JavaScript works, but it means two unrelated types with the same shape are interchangeable.
11What are excess property checks?Structural typing
When you assign an object literal directly to a typed target, TypeScript flags properties that aren't in the type, even though structural typing would otherwise allow extra properties. This catches typos like spelling a key wrong in a config. The check only applies to fresh object literals — assign through a variable and it relaxes, which is a common surprise.
12What's the difference between a type assertion and narrowing, and why are assertions risky?Structural typing
Narrowing proves a type to the compiler through a runtime check, so it's safe. An assertion (x as Foo) just tells the compiler to trust you without any check — if you're wrong, you get a runtime error the type system can't catch. Use assertions sparingly, for cases the compiler genuinely can't follow, and prefer guards/validation that actually verify the value.
Preparation tips
Walk in ready.
- Practise writing a mapped type from scratch
- Model a state machine with a discriminated union
- Know when an assertion is lying to the compiler
- Use keyof to keep object access type-safe
Ready for the real thing?
Run a 6-question TypeScript mock interview, answer out loud, and get a readiness score with tips and model answers.
More intermediate interviews