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
Type annotations
Type inference
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]
Union types
Intersection types
Literal types
Literal unions as restricted value sets
Type aliases
Interfaces
B. Special & top/bottom types
any disables checking
Implicit any
unknown — the safe top type
never — the bottom type
void — ignored return value
undefined vs void assignability
null / undefined under strictNullChecks
NonNullable<T>
PropertyKey = string | number | symbol
unique symbol identities
C. Assignability & compatibility
Structural typing (members, not names)
Extra members still satisfy a smaller shape
Assignability rules
Freshness of object literals
Excess-property checking
Weak types (all-optional shapes)
Widening
Literal widening (why "ready" infers as string)
Non-widening literals
Contextual typing
D. Declarations & inference
let widens
const keeps literals
as const assertions
Best common type
Return-type 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
Required properties
Optional properties ?
Missing vs present-but-undefined
Readonly properties
readonly is shallow
Index signatures
String index signatures
Number index signatures
Symbol index signatures
Declared props must fit the index signature
Call signatures on object types
Construct signatures (new (...))
Hybrid callable-with-properties types
Interface extends
Extending several interfaces
Interface declaration merging
Composing object types with &
Self-referential object types
Recursive aliases (JSON, trees)
Nominal branding patterns
F. Functions
Parameter annotations
Return annotations
Optional parameters
Default parameters
Rest parameters
Function type expressions (v: string) => number
Callback types
Contextually typed callbacks
Call-signature object types
Construct-signature object types
Function overloads
Overload signatures
The (hidden) implementation signature
Overload resolution & compatibility
Prefer unions over needless overloads
Generic functions
Generic relationships through callbacks
this parameters
this: void callbacks
this return types (fluent APIs)
Parameter destructuring
Typing destructured parameters
Readonly array parameters
Variadic tuple parameters
Spread argument typing
G. Narrowing & control-flow analysis
Control-flow analysis
typeof narrowing
Truthiness narrowing
Equality narrowing
in operator narrowing
instanceof narrowing
Assignment-based narrowing
Reachability-based narrowing
Discriminated unions
Discriminant properties
Exhaustive switch
Exhaustiveness checks with never
User-defined type predicates
Predicate syntax value is T
Assertion functions
asserts value
asserts value is T
Aliased-condition narrowing
Narrowing through destructuring
Narrowing generic values
Narrowing dotted names
Narrowing invalidated by mutation
Narrowing lost in callbacks
Nullable-value narrowing
Optional-chain narrowing limits
H. Assertions & operators
Type assertions as T
Angle-bracket assertions <T>v
Double assertions as unknown as T
Non-null assertion v!
Definite-assignment assertions p!: T
The satisfies operator
as const vs satisfies
Value-level typeof
Type-level typeof
The keyof operator
I. Generics
Type parameters
Generic type aliases
Generic interfaces
Generic classes
Generic constraints
extends constraints
K extends keyof T
Multiple type parameters
Relationships between type parameters
Default type arguments
Explicit type arguments
Type-argument inference
Generic factory functions
Constructor constraints
Generic higher-order functions
Propagating type parameters
Generic rest tuples
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
T[number]
Tuple element extraction
keyof typeof patterns
Conditional types T extends U ? X : Y
Constraints inside conditional types
Inference inside conditional types
The infer keyword
Inferring function return types
Inferring parameter tuples
Inferring promise values
Nested conditional types
Recursive conditional types
Distributive conditional types
Preventing distributivity [T] extends [U]
Mapped types
Mapping over keyof
Mapped-type modifiers
Adding / removing readonly
Adding / removing optionality
Key remapping with as
Filtering keys (remap to never)
Template-literal types
Template-literal union expansion (cross product)
Pattern matching with template literals
Intrinsic string-manipulation types
Uppercase<T>
Lowercase<T>
Capitalize<T>
Uncapitalize<T>
K. Built-in utility types
Partial<T>
Required<T>
Readonly<T>
Pick<T, K>
Omit<T, K>
Record<K, V>
Exclude<T, U>
Extract<T, U>
Parameters<T>
ConstructorParameters<T>
ReturnType<T>
InstanceType<T>
ThisParameterType<T>
OmitThisParameter<T>
ThisType<T>
Awaited<T>
NoInfer<T>
Composing utility types
Implementing your own utility types
L. Compiler configuration
strict
strictNullChecks
noImplicitAny
strictFunctionTypes
strictPropertyInitialization
noUncheckedIndexedAccess
exactOptionalPropertyTypes
useUnknownInCatchVariables
noImplicitOverride
noFallthroughCasesInSwitch
noImplicitReturns
target
lib
module
moduleResolution (nodenext / bundler)
verbatimModuleSyntax
isolatedModules
declaration
declarationMap
sourceMap
incremental (.tsbuildinfo)
composite
paths
types / typeRoots
extends in tsconfig
include / exclude
skipLibCheck
M. Modules & package architecture
ESM vs CommonJS
Type-only imports / exports
Import elision
Package exports field
Package imports field
Conditional exports
.d.ts declaration files
Ambient declarations
Module declarations
Module augmentation
Global augmentation
Namespace declarations
Project references
Monorepo configuration
Library publishing
Dual-package hazard
N. Classes
Field declarations and their inferred types
Definite-assignment fields p!: T
readonly fields
Constructor overload signatures
super() must run before this
Field initializers run in declaration order
Parameter properties (constructor(public x))
Getter/setter pairs
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
Static members
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
ctx.addInitializer
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
Typing children
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
noEmitOnError
noEmit for type-checking only
rootDir
moduleDetection
allowJs versus checkJs
// @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.
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