Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Strong JavaScript and TypeScript interview answers explain not only what a feature does, but when it is useful and what can go wrong in production. This first part covers five foundational topics: closures, promises and asynchronous flow, TypeScript’s role, type inference and narrowing, and generics. The supplied title does not specify a definitive question list, so these are well-supported core topics rather than a claim about a particular interview’s questions.
What is a closure, and why does it matter in production?
A closure is a function together with access to the lexical environment in which it was created. That lets an inner function use bindings from an outer function even after the outer function has returned. MDN describes closures as functions bundled with references to their surrounding state (MDN’s JavaScript guide to closures).
Example: a handler that retains configuration
function createRequestHandler(apiBaseUrl) {
return function handleRequest(path) {
return fetch(`${apiBaseUrl}${path}`);
};
}
const handleRequest = createRequestHandler("https://api.example.com");
The returned handler can still read apiBaseUrl because it closes over that binding. The same pattern can keep module state private or let a callback retain the state it needs. In production, pay attention to what a long-lived callback captures and how long that callback remains reachable: captured state remains reachable with it. Closures are not inherently memory leaks; unnecessarily retaining large or obsolete state is the concern.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →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. Inside it, await waits for a value or promise to settle, then evaluates to the fulfillment value or throws the rejection. It suspends that async function, not the entire JavaScript program. See MDN’s guide to using promises and its async JavaScript learning guide.
Choose sequential or concurrent work based on dependencies
Suppose a page needs a profile and feature flags. If the flags request requires an identifier returned by the profile request, the operations are dependent and should be sequenced. If both requests can be made independently, start both before awaiting their results:
async function loadPageData(userId) {
const [profile, flags] = await Promise.all([
fetchProfile(userId),
fetchFeatureFlags(userId)
]);
return { profile, flags };
}
Promise.all() rejects if any input promise rejects. Use it when the caller needs every result to proceed. If each outcome needs to be inspected and partial results may be useful, Promise.allSettled() waits for all inputs to settle and reports each result. Starting independent work together can avoid needless waiting, but the actual benefit depends on the dependency graph and application behavior; it is not a guaranteed performance improvement.
Handle failures where the recovery decision belongs
With async/await, use try/catch when the function can take a meaningful recovery action or add useful context. Promise chains can handle failures with .catch(). Catching an error and continuing is appropriate only when that operation is genuinely optional and a safe fallback is defined; otherwise, let the failure reach a layer that can handle it. Promise callbacks run asynchronously rather than in the current call stack, and asynchronous I/O does not make CPU-heavy JavaScript non-blocking. CPU-bound JavaScript can still block the main thread (MDN’s JavaScript language overview).
What does TypeScript do, and what does it not do?
TypeScript adds a type system to JavaScript and checks programs before they run. The TypeScript Handbook puts its goal this way: “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).” Read the TypeScript Handbook introduction.
Rank #3
Use types to make assumptions visible
For an API response, a TypeScript type can describe the fields the program expects and help catch inconsistent use during development. But a type annotation does not inspect or validate the bytes received at runtime. Data from an external service remains untrusted until the running program checks it. Treat runtime parsing or validation at the boundary as a separate step from static type checking.
When should you rely on inference, and when should you narrow a type?
TypeScript often infers a variable’s type from its initializer and can infer callback parameter types from context. An explicit annotation is useful when it clarifies intent or when inference lacks enough context; adding one everywhere is not required. See the documentation on type inference and everyday types.
Rank #4
- Used Book in Good Condition
Narrow unions with evidence from runtime checks
A union type describes a value that could have more than one type. JavaScript checks such as typeof, equality tests, in, and instanceof can let TypeScript narrow that union in a branch. For example, check a value before calling a method that is valid only for one possibility:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutefunction formatId(id: string | number): string {
if (typeof id === "number") {
return id.toFixed(0);
}
return id.trim();
}
The check supplies the runtime evidence for the branch; the resulting type lets the checker verify that the operation is appropriate. One JavaScript edge case matters: typeof null is "object". A typeof value === "object" check alone therefore does not prove that a value is non-null.
Best Value
Represent success and failure as distinct cases
For a result that can succeed or fail, a discriminated union makes branch-specific fields explicit:
type Result =
| { status: "success"; data: string }
| { status: "error"; message: string };
function displayResult(result: Result): string {
if (result.status === "success") {
return result.data;
}
return result.message;
}
Checking the discriminant establishes which case is present before accessing its specific property. This makes the expected runtime branch and the type-level contract reinforce each other.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.When should you use a generic instead of any?
Use a generic when an API should accept different types while preserving a relationship between its inputs and outputs. For example, function identity<T>(value: T): T can accept a string or a number and returns the corresponding type. The generic parameter carries that relationship through the function. The TypeScript Handbook explains generics in detail.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
any discards useful type information, so callers lose much of the checking that could reveal invalid operations. A generic is not automatically better simply because it is more abstract: choose the simplest type that expresses the API’s real contract. Add a constraint when the implementation needs capabilities that an unrestricted T does not promise.
Quick Recap
How should you frame these answers in an interview?
- Define the mechanism: explain what the language feature guarantees, such as a closure retaining access to its lexical environment.
- Connect it to a decision: identify the production condition that affects the choice, such as whether two requests are independent or whether partial results are acceptable.
- Name the boundary: distinguish compile-time checking from runtime validation, or asynchronous waiting from CPU work that can block the main thread.
- Keep the example proportional: show the smallest example that demonstrates the contract, then explain what a maintainer must still handle.
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.

