TypeScript

Fundamentals & Type System

1

What is TypeScript and why use it over JavaScript?

TypeScript is a statically-typed superset of JavaScript that compiles to plain JavaScript. It adds optional type annotations, interfaces, and compile-time type checking.

Benefits:

  • Catches errors at compile time (before runtime)
  • Better IDE support (autocompletion, refactoring)
  • Self-documenting code through types
  • Safer refactoring in large codebases

What problems does this solve?

  • Prevents chaotic runtime type errors natively.
  • Allows powerful static analysis dynamically.
  • Improves developer experience radically via autocomplete.
2

What is the difference between any, unknown, and never?

  • any: Disables type checking entirely. Anything goes—avoid when possible.
  • unknown: The type-safe counterpart to any. You must narrow/check the type before using it.
  • never: Represents values that never occur (e.g., a function that always throws or has an infinite loop).

What problems does this solve?

  • Provides strict dynamic typing bindings safely.
  • Requires explicit type checking smoothly.
  • Represents unreachable code mathematically.
3

What is the difference between interface and type?

Both define object shapes, but:

Featureinterfacetype
Extend/Inheritextends& (intersection)
Declaration merging✅ Yes❌ No
Primitives, unions, tuples❌ No✅ Yes

Rule of thumb: Use interface for object shapes (especially public APIs). Use type for unions, primitives, or complex type expressions.

What problems does this solve?

  • Allows class implementations smoothly.
  • Handles complex unions dynamically.
  • Standardizes structural object shaping.
4

What is Type Inference?

TypeScript automatically infers types when you don't explicitly annotate them.

Inference reduces boilerplate while still providing type safety.

What problems does this solve?

  • Reduces heavy manual typing boilerplate.
  • Analyzes assignment logic intelligently.
  • Keeps code exceptionally clean organically.
5

What are Literal Types?

Types that represent exact values, not just general types.

Literal types are the building blocks of discriminated unions.

What problems does this solve?

  • Restricts generic strings into exact allowed variants cleanly.
  • Creates extremely safe logic states natively.
  • Replaces magic strings dynamically.
6

What is a Tuple in TypeScript?

A fixed-length array where each element has a specific type.

What problems does this solve?

  • Binds strict arrays cleanly.
  • Allows multiple exact return types.
  • Simulates record-like structures efficiently.
7

What are Enums and when should you use them?

Enums define a set of named constants.

Caution: Numeric enums create runtime code. Consider using as const objects or union types as lighter alternatives:

What problems does this solve?

  • Groups static constants natively.
  • Provides exact mapping intelligently.
  • Eliminates magic specific numbers explicitly.
8

What is the difference between null and undefined in TypeScript?

  • undefined: Variable declared but not assigned; default for optional properties.
  • null: Explicitly assigned "no value."

With strictNullChecks enabled, both are separate types and not assignable to other types without explicit checks.

What problems does this solve?

  • Tracks missing keys flawlessly.
  • Represents intentional emptiness natively.
  • Enforces strict null checks safely.

Generics

9

What are Generics and why are they useful?

Generics allow you to write reusable, type-safe code that works with multiple types.

Without generics, you'd have to use any (losing type safety) or write duplicate functions for each type.

What problems does this solve?

  • Enables highly reusable typed utilities.
  • Prevents chaotic any types organically.
  • Allows flexible typed architectures.
10

What are Generic Constraints?

Using extends to limit what types a generic can accept.

What problems does this solve?

  • Restricts generic loops strictly.
  • Enforces structural requirements naturally.
  • Prevents completely generic invalid inputs.
11

What is the infer keyword?

Used inside conditional types to extract/infer a type from another type.

infer R captures the return type and makes it available as R.

What problems does this solve?

  • Extracts nested types dynamically.
  • Analyzes complex mapped logic seamlessly.
  • Pulls return types smoothly.
12

What does keyof do?

Creates a union type of all property keys of a type.

Often used with generics to create type-safe property access.

What problems does this solve?

  • Generates literal dynamic maps continuously.
  • Maps object keys purely.
  • Reduces duplication natively.
13

What is typeof in TypeScript (type context)?

Extracts the type from a value (different from JavaScript's runtime typeof).

What problems does this solve?

  • Extracts type signatures programmatically.
  • Infers complex JS maps dynamically.
  • Bridges pure JS bindings natively.

Type Narrowing & Guards

14

What is Type Narrowing?

The process of refining a variable's type within a conditional block using control flow analysis.

What problems does this solve?

  • Ensures safe union extraction strictly.
  • Guides the compiler path clearly.
  • Prevents accessing missing properties.
15

What is a Type Guard?

A function that performs a runtime check and tells TypeScript the type within that scope.

The value is string return type is the type predicate.

What problems does this solve?

  • Creates reusable narrowing checks.
  • Validates complex backend payloads safely.
  • Instructs the compiler dynamically explicitly.
16

What is a Discriminated Union?

A pattern where each member of a union has a common literal property (the "discriminant") that TypeScript uses to narrow the type.

What problems does this solve?

  • Solves extremely complex object unions purely.
  • Uses shared constants strictly.
  • Allows switch statement exhaustiveness.
17

What is the in operator for narrowing?

Checks if a property exists in an object, narrowing the type accordingly.

What problems does this solve?

  • Checks property existence efficiently.
  • Works safely without class structures.
  • Narrows types purely structurally.

Utility Types

18

What are Utility Types? Name the most common ones.

Built-in generic types that transform other types.

UtilityDescription
Partial<T>Makes all properties optional
Required<T>Makes all properties required
Readonly<T>Makes all properties readonly
Pick<T, K>Selects a subset of properties
Omit<T, K>Removes a subset of properties
Record<K, V>Creates an object type with keys K and values V
ReturnType<T>Extracts the return type of a function
Parameters<T>Extracts parameter types as a tuple
NonNullable<T>Removes null and undefined from T
Awaited<T>Unwraps Promise types

What problems does this solve?

  • Molds existing types drastically.
  • Prevents duplicating identical mapped interfaces.
  • Simplifies state definitions.
19

What is Readonly and how does it differ from const?

  • const: Prevents reassignment of a variable, but object properties can still be mutated.
  • Readonly<T>: Makes all properties of an object immutable at the type level.

What problems does this solve?

  • Freezes object mutations securely.
  • Prevents modifying arrays natively.
  • Works deeply dynamically flawlessly.
20

What is as const (const assertion)?

Tells TypeScript to infer the narrowest possible type (literal types, readonly arrays/objects).

What problems does this solve?

  • Locks arrays into Tuples cleanly.
  • Transforms strings exclusively naturally.
  • Prevents literal type widening natively.

Advanced Types

21

What are Mapped Types?

Types that iterate over keys of another type to create a new type.

You can also remap keys:

What problems does this solve?

  • Iterates pure type maps drastically.
  • Allows building complex modifiers natively.
  • Transforms keys elegantly safely.
22

What are Conditional Types?

Types that choose between two options based on a condition.

What problems does this solve?

  • Applies conditional logic during compile natively.
  • Builds deeply mapped architectures inherently.
  • Analyzes union structures dynamically.
23

What are Template Literal Types?

Types that use string template syntax to create new string literal types.

Useful for typing string patterns (CSS units, event handlers, routes).

What problems does this solve?

  • Generates string permutations strictly.
  • Types dynamic CSS classes properly.
  • Molds exact structural bindings natively.
24

What is an Index Signature?

Defines the type for dynamic property names.

What problems does this solve?

  • Allows dynamic dictionary maps.
  • Types unknown generic keys safely.
  • Shapes backend JSON flawlessly.
25

What is the satisfies operator (TypeScript 4.9+)?

Validates that a value conforms to a type while preserving the narrowest inferred type.

Without satisfies, using a type annotation would widen the types.

What problems does this solve?

  • Validates exact types properly.
  • Prevents type widening strictly.
  • Preserves exact string literals natively.

Functions & Classes

26

What is Function Overloading in TypeScript?

Defining multiple function signatures for different parameter types.

The implementation signature is not visible to callers—only the overload signatures.

What problems does this solve?

  • Shapes complex polymorphic returns.
  • Allows clean specific API signatures.
  • Molds parameter permutations cleanly.
27

What is the difference between public, private, and protected?

ModifierClassSubclassOutside
public
protected
private

Note: These are compile-time only. At runtime, all properties are accessible (use # for true private fields).

What problems does this solve?

  • Exposes structural APIs naturally.
  • Hides internal private state securely.
  • Allows extending subclass logic properly.
28

What are Abstract Classes?

Classes that cannot be instantiated directly—only extended. They can contain abstract methods that subclasses must implement.

What problems does this solve?

  • Creates strictly enforced blueprints cleanly.
  • Prevents instantiating base logic.
  • Allows shared baseline architectures.

Practical TypeScript

29

What is Declaration Merging?

When TypeScript combines multiple declarations with the same name into one.

This is why interface is preferred for public APIs—consumers can extend them.

What problems does this solve?

  • Allows augmenting third-party modules.
  • Fixes missing library types seamlessly.
  • Extends window properties flawlessly.
30

What is strict mode in tsconfig.json?

A compiler flag that enables a set of strict type-checking options:

  • strictNullChecks: null/undefined are not assignable to other types
  • noImplicitAny: Error when type is implicitly any
  • strictFunctionTypes: Stricter function type checking
  • strictBindCallApply: Check bind, call, apply methods
  • strictPropertyInitialization: Class properties must be initialized

Best practice: Always enable strict: true in new projects for maximum type safety.

What problems does this solve?

  • Enforces extremely rigorous type safety globally.
  • Eliminates implicit any loopholes completely.
  • Prevents destructive null-reference bugs natively.
31

What are Decorators in TypeScript?

Decorators are special declarations that can be attached to classes, methods, properties, or parameters to modify their behavior. They use the @expression syntax.

Note: Decorators require experimentalDecorators: true in tsconfig. TypeScript 5.0+ also supports the new TC39 standard decorators.

What problems does this solve?

  • Modifies classes gracefully.
  • Injects metadata neatly dynamically.
  • Provides framework structural capabilities natively.
32

What is Module Augmentation?

Extending existing modules or libraries with additional type declarations without modifying the original source.

Useful for adding custom properties to third-party library types.

What problems does this solve?

  • Enhances global types directly.
  • Molds existing unowned classes safely.
  • Enables complex Vue/React typings natively.
33

What is an Assertion Function?

A function that throws an error if a condition is not met, and tells TypeScript to narrow the type after the call.

What problems does this solve?

  • Verifies exact runtime expectations dynamically.
  • Halts invalid executions explicitly.
  • Instructs compiler logic radically.
34

What are Branded Types (Nominal Typing)?

A pattern to create distinct types that are structurally identical but treated as different by TypeScript.

Prevents accidentally mixing semantically different values.

What problems does this solve?

  • Creates strict purely nominal types natively.
  • Distinguishes between identical structural strings.
  • Prevents mixing distinct unique ids safely.
35

What is Covariance and Contravariance?

How subtype relationships work in generic types:

  • Covariance: If Dog extends Animal, then Array<Dog> is assignable to Array<Animal>. (Output positions)
  • Contravariance: Function parameters work in reverse—(animal: Animal) => void is assignable to (dog: Dog) => void. (Input positions)

Understanding this helps when you get unexpected type errors with callbacks.

What problems does this solve?

  • Defines assignment logic profoundly.
  • Calculates complex parameter boundaries cleanly.
  • Prevents invalid generic casting natively.
36

What is the noUncheckedIndexedAccess compiler option?

When enabled, accessing an array or object by index includes undefined in the type.

This catches potential "index out of bounds" bugs at compile time.

What problems does this solve?

  • Flags unsafe array structures rigidly.
  • Treats all index maps as potentially undefined.
  • Prevents random array crashing cleanly.
37

What is a .d.ts file?

A declaration file that contains only type information (no runtime code). Used to:

  • Provide types for JavaScript libraries
  • Separate type definitions from implementation
  • Describe the shape of external modules

What problems does this solve?

  • Publishes strict structural templates.
  • Allows typing pure JS files beautifully.
  • Shares ambient declarations natively globally.
38

What is the difference between import type and regular import?

  • import type: Imports only types; completely erased at runtime. Ensures no runtime dependency on the module.
  • Regular import: Imports values and/or types; may include runtime code.

Use import type when you only need types to reduce bundle size and avoid circular dependency issues.

What problems does this solve?

  • Eliminates runtime code bloat safely.
  • Strips pure types during compilation natively.
  • Prevents circular class dependencies smoothly.
39

What is this typing in TypeScript?

You can explicitly type this as the first parameter in a function (it's erased at runtime).

What problems does this solve?

  • Chains class methods fluidly natively.
  • Allows polymorphic object returns dynamically.
  • Maintains precise builder structures inherently.
40

What is Exclude vs Extract utility type?

Both filter union types:

  • Exclude<T, U>: Removes types from T that are assignable to U.
  • Extract<T, U>: Keeps only types from T that are assignable to U.

What problems does this solve?

  • Splits complex generic unions quickly.
  • Retrieves exact literal maps safely.
  • Builds dynamic logic subsets cleanly.