Back
Keentune
Adaptive skill practice — find your level, get sharper.
TypeScript practice
Master the type system senior interviews test
Go deep on TypeScript’s type system — generics and constraints, inference, narrowing, unions and discriminated unions, conditional and mapped types, the utility types, and the strictness rules — through real code-based questions with clear explanations. Built to take you from solid to expert and to ace the TypeScript questions in senior-engineer interviews. Part of the Developer track.
• Meets you at your level — never too easy, never too hard.
• Adapts every question to how you’re doing.
• Tracks your level over time. Skill practice, not a test.
What you’ll master
Follow the curriculum from foundations through advanced practice. Each line is a concept the adaptive question bank can teach and test.
A. Type-system foundations
•
TypeScript ↔ JavaScript: types are erased at emit
•
Static checking vs runtime behavior
•
Primitive types (string/number/boolean/bigint/symbol/null/undefined)
•
The object type (any non-primitive)
•
The {} type (any non-nullish value)
•
The boxed Object interface (avoid)
•
Array types: T[] vs Array<T>
•
Tuple types (fixed positions, per-element types)
•
Named tuple elements [x: number, y: number]
•
Optional tuple elements [number, string?]
•
Tuple rest elements [string, ...number[]]
•
Readonly tuples readonly [number, number]
•
Literal unions as restricted value sets
B. Special & top/bottom types
•
unknown — the safe top type
•
void — ignored return value
•
undefined vs void assignability
•
null / undefined under strictNullChecks
•
PropertyKey = string | number | symbol
•
unique symbol identities
C. Assignability & compatibility
•
Structural typing (members, not names)
•
Extra members still satisfy a smaller shape
•
Freshness of object literals
•
Excess-property checking
•
Weak types (all-optional shapes)
•
Literal widening (why "ready" infers as string)
D. Declarations & inference
•
Parameter-type inference from context
•
Generic inference from arguments
•
Multiple inference candidates
•
Inference direction and flow
•
When to annotate instead of infer
E. Object types
•
Missing vs present-but-undefined
•
Declared props must fit the index signature
•
Call signatures on object types
•
Construct signatures (new (...))
•
Hybrid callable-with-properties types
•
Extending several interfaces
•
Interface declaration merging
•
Composing object types with &
•
Self-referential object types
•
Recursive aliases (JSON, trees)
•
Nominal branding patterns
F. Functions
•
Function type expressions (v: string) => number
•
Contextually typed callbacks
•
Call-signature object types
•
Construct-signature object types
•
The (hidden) implementation signature
•
Overload resolution & compatibility
•
Prefer unions over needless overloads
•
Generic relationships through callbacks
•
this return types (fluent APIs)
•
Typing destructured parameters
•
Readonly array parameters
•
Variadic tuple parameters
G. Narrowing & control-flow analysis
•
Assignment-based narrowing
•
Reachability-based narrowing
•
Exhaustiveness checks with never
•
User-defined type predicates
•
Predicate syntax value is T
•
Aliased-condition narrowing
•
Narrowing through destructuring
•
Narrowing generic values
•
Narrowing invalidated by mutation
•
Narrowing lost in callbacks
•
Nullable-value narrowing
•
Optional-chain narrowing limits
H. Assertions & operators
•
Angle-bracket assertions <T>v
•
Double assertions as unknown as T
•
Definite-assignment assertions p!: T
I. Generics
•
Multiple type parameters
•
Relationships between type parameters
•
Generic factory functions
•
Generic higher-order functions
•
Propagating type parameters
•
Generic discriminated unions
•
Constraint vs type argument
•
Choosing the least restrictive constraint
J. Type manipulation
•
Indexed-access types T[K]
•
Indexing with a union of keys
•
Tuple element extraction
•
Conditional types T extends U ? X : Y
•
Constraints inside conditional types
•
Inference inside conditional types
•
Inferring function return types
•
Inferring parameter tuples
•
Inferring promise values
•
Nested conditional types
•
Recursive conditional types
•
Distributive conditional types
•
Preventing distributivity [T] extends [U]
•
Adding / removing readonly
•
Adding / removing optionality
•
Filtering keys (remap to never)
•
Template-literal union expansion (cross product)
•
Pattern matching with template literals
•
Intrinsic string-manipulation types
K. Built-in utility types
•
ConstructorParameters<T>
•
Implementing your own utility types
L. Compiler configuration
•
strictPropertyInitialization
•
noUncheckedIndexedAccess
•
exactOptionalPropertyTypes
•
useUnknownInCatchVariables
•
noFallthroughCasesInSwitch
•
moduleResolution (nodenext / bundler)
•
incremental (.tsbuildinfo)
M. Modules & package architecture
•
Type-only imports / exports
N. Classes
•
Field declarations and their inferred types
•
Definite-assignment fields p!: T
•
Constructor overload signatures
•
super() must run before this
•
Field initializers run in declaration order
•
Parameter properties (constructor(public x) )
•
A setter may accept a wider type than its getter
•
A get-only accessor is readonly from outside
•
The accessor keyword (TS 4.9+)
•
public / protected / private
•
private members defeat structural compatibility
•
#private is enforced at runtime
•
Private constructors and the singleton pattern
•
Polymorphic this in a static method
•
Abstract classes cannot be instantiated
•
Abstract members must be implemented
•
implements checks conformance, inherits nothing
•
implements accepts any object type
•
Class expressions are values
•
this return types for subclass-safe chaining
•
abstract new construct signatures
•
Method overloads inside a class body
O. Enums
•
Numeric enums auto-increment from zero
•
String enums have no reverse mapping
•
Heterogeneous enums mix string and numeric members
•
Numeric enums emit a reverse mapping
•
Computed members must follow initialized ones
•
An enum name is both a value and a type
•
const enum members are inlined
•
const enum versus isolatedModules
•
Literal unions and as const as alternatives
P. Iterators, generators and symbols
•
[Symbol.iterator] makes a value iterable
•
for...of requires the iterable protocol
•
for...in iterates keys, for...of values
•
Generator<Y, R, N> from a function*
•
yield* delegates to another iterable
•
for await...of and async iterables
•
unique symbol as a property key
•
Symbol.for shares by key; Symbol() never does
Q. Decorators
•
Standard decorators versus experimentalDecorators
•
A class decorator runs once, at definition
•
The context parameter (ClassMethodDecoratorContext )
•
Returning a value replaces the decorated member
•
Evaluation versus application order
R. Mixins
•
The GConstructor constructor-type alias
•
Why the base takes (...args: any[])
•
A mixin returns an anonymous class expression
•
Applying several mixins by nesting
S. JSX
•
A JSX expression has type JSX.Element
•
Lowercase tags are intrinsic, capitalized are components
•
Attributes are checked against the props type
•
The jsx compiler option chooses the emit
•
A generic arrow needs <T,> in a .tsx file
T. The compiler as a program: CLI, emit and JavaScript interop
•
A tsconfig.json marks a project root
•
Naming files on the CLI bypasses tsconfig
•
tsc emits JavaScript despite type errors
•
noEmit for type-checking only
•
// @ts-check with JSDoc types
•
Triple-slash directives must lead the file
•
Import attributes (with ) replace assert
•
The TypeScript 7 native compiler
Keentune is not affiliated with or endorsed by the organizations whose documentation informs these maps.
Start practicing — it’s free
Explore all skills on Keentune
All exam, test, and product names and trademarks are the property of their respective owners and are used here for identification and reference only. Keentune is independent study practice — not affiliated with, authorized, or endorsed by any of these organizations.
© 2026 SportaApp LLC