October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

JavaScript and TypeScript Interview Questions: Core Concepts in Production, Part 1

Understand core JavaScript and TypeScript interview concepts through practical examples, with attention to dependencies, errors, runtime validation, and maintainable APIs.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Strong answers to JavaScript and TypeScript interview questions connect language rules to decisions developers make in real code. This guide explains closures, promises and async/await, TypeScript’s role, inference and narrowing, and generics—with compact examples and the production trade-offs each concept brings.

What does a JavaScript closure do?

A closure is a function together with access to the lexical environment in which it was created. It can continue to use surrounding variables even after the outer function has returned. That makes closures useful for callbacks and for keeping state private. MDN’s closure guide describes the relationship between a function and references to its surrounding state.

As an Amazon Associate I earn from qualifying purchases.

Example: encapsulating request configuration

function createRequestHandler(baseUrl) {
  return function request(path) {
    return fetch(`${baseUrl}${path}`);
  };
}

const requestApi = createRequestHandler("/api");
requestApi("/profile");

The returned function retains access to baseUrl, so callers can use the configured request function without passing that value each time. In production, the same pattern can retain callback state or module-private values. The lifecycle matters: captured state remains reachable while a closure that references it remains reachable. A closure is not automatically a memory leak; investigate what it captures and how long callbacks or handlers are retained.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do promises and async/await work?

A Promise represents the eventual fulfillment or rejection of an asynchronous operation. An async function always returns a promise. Within it, await suspends that function until the awaited value settles; it then produces the fulfillment value or throws the rejection. This does not freeze the entire JavaScript program. MDN’s promise guide covers promises, chaining, and composition, while its async JavaScript learning guide explains async/await.

Choose sequential or concurrent work by dependency

Suppose a page loads a profile and feature flags. If the flag request needs an identifier returned by the profile request, wait for the profile first. If the requests are independent, start both before awaiting their results:

async function loadPage() {
  const profilePromise = fetch("/api/profile");
  const flagsPromise = fetch("/api/flags");

  const [profileResponse, flagsResponse] = await Promise.all([
    profilePromise,
    flagsPromise,
  ]);

  return {
    profile: await profileResponse.json(),
    flags: await flagsResponse.json(),
  };
}

This structure permits independent operations to progress together; it does not guarantee a particular performance improvement. That depends on the actual dependency graph and application behavior. Sequential await is the clearer choice when one operation needs another’s result.

Promise.all() rejects if any input rejects. Use it when the combined result is only useful if every operation succeeds, and handle that rejection at an appropriate boundary. Promise.allSettled() waits for every input to settle and reports each outcome, which suits workflows where partial results can be used. The right choice depends on whether every result is required and what recovery or fallback is safe.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle failures without hiding them

Use try/catch around awaited work when the function can recover, add context, or pass a meaningful failure to its caller. Promise chains can handle failures with rejection handlers; async/await changes the syntax and error-flow shape, not the underlying promise behavior. Promise callbacks run asynchronously rather than in the middle of the current call stack.

async function loadOptionalSettings() {
  try {
    const response = await fetch("/api/settings");
    if (!response.ok) throw new Error("Settings request failed");
    return await response.json();
  } catch (error) {
    // A fallback is appropriate only if the feature can safely use it.
    return { compactMode: false };
  }
}

Returning a fallback is a product decision, not a generic way to make errors disappear. If the missing data is essential, let the failure reach code that can show an error or retry.

Does asynchronous I/O make CPU-heavy JavaScript non-blocking?

No. Asynchronous I/O allows the program to continue while waiting for an operation such as a network response, but CPU-bound JavaScript can still block the main thread while it runs. MDN’s JavaScript language overview distinguishes asynchronous behavior from work that occupies the thread. Keep expensive computation in mind when diagnosing an unresponsive interface; making unrelated network calls asynchronous does not make that computation non-blocking.

What is TypeScript for, and what does it not do?

TypeScript is a static type checker for JavaScript programs: it checks types before the program runs. Its type system helps surface unsafe operations during development and documents expectations in code. As the TypeScript Handbook puts it, “The goal of TypeScript is to be a static typechecker for JavaScript programs – in other words, a tool that runs before your code runs (static) and ensures that the types of the program are correct (typechecked).”

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use types to reason about an API boundary, not to validate the network

A declared type can express the shape your application expects from an API:

type Profile = {
  id: string;
  displayName: string;
};

const profile: Profile = await response.json();

That annotation helps TypeScript check how the value is used in the program. It does not inspect the received bytes or prove that an external server actually returned those fields. For untrusted data, treat parsing and runtime validation as a separate boundary step before relying on the value. The distinction follows from TypeScript’s static, pre-execution role; a type annotation alone is not a runtime check.

When should you annotate a type, and when should you let TypeScript infer it?

TypeScript often infers a variable’s type from its initializer and can infer callback parameter types from context. For example, const count = 3 gives TypeScript enough information to understand that count is a number. An explicit annotation is useful when it makes a contract or intent clearer, or when inference lacks enough context; adding one to every local variable can add noise without improving safety. See the Handbook’s guides to type inference and everyday types.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How does narrowing make union types safer?

A union describes a value that may have more than one type. Narrowing uses runtime checks—such as typeof, equality, in, or instanceof—to establish which case applies so code can safely use that case’s operations. The TypeScript narrowing guide explains how control flow refines types.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Branch on a discriminant before using case-specific fields

type Result =
  | { status: "success"; data: string }
  | { status: "error"; message: string };

function describe(result: Result) {
  if (result.status === "success") {
    return result.data;
  }
  return result.message;
}

Checking status proves which shape is present in each branch. The same principle applies to a string | number: test its runtime type before calling methods that only make sense for one branch. Be careful with null: JavaScript reports typeof null as "object", so a typeof value === "object" check does not by itself exclude null from an object union.

When should you use a generic instead of any?

Use a generic when a reusable API should accept different types while preserving a meaningful relationship between its inputs and outputs. Use any only when discarding that type information is genuinely intended; it weakens the checks that make TypeScript useful. The TypeScript generics guide explains how type parameters express reusable contracts.

Preserve the input type through the result

function identity<T>(value: T): T {
  return value;
}

const name = identity("Sam");
const total = identity(42);

The function works with varying inputs while returning the same type supplied by the caller. By contrast, an any-based version would discard that relationship and let callers use the result without useful type checks. A generic is not a reason to make every function abstract: choose the simplest contract that captures the real relationship, and add a constraint only when the implementation needs capabilities beyond an unconstrained T.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.