5 exercises — closure, Promise, type narrowing, generics, destructuring — the core concepts every JS/TS developer discusses daily.
0 / 14 completed
1 / 14
A closure in JavaScript is best described as:
A closure is a function bundled together with references to its surrounding state (lexical environment). Closures are used for data encapsulation, factory functions, and callbacks. Example: function counter() { let n=0; return () => ++n; }
2 / 14
Complete the sentence: "Instead of using callbacks, the team refactored the code to use _____ with async/await, making the error handling much cleaner."
Promises represent the eventual result (or failure) of an asynchronous operation. async/await is syntactic sugar over Promises — an async function always returns a Promise, and await pauses execution until the Promise settles.
3 / 14
In TypeScript, type narrowing means:
Type narrowing is when TypeScript refines a broader type to a more specific one inside a conditional block. For example, after if (typeof x === "string"), TypeScript knows x is a string inside that block. Common narrowing guards: typeof, instanceof, in, and custom type predicates (x is T).
4 / 14
TypeScript generics are used to:
Generics let you write flexible, reusable components that work with different types without losing type safety. Example: function identity<T>(arg: T): T { return arg; }. Common in utility types like Array<T>, Promise<T>, Record<K, V>.
5 / 14
"We can use destructuring to extract just the fields we need." Which of the following is an example of object destructuring?
Destructuring is a concise syntax to unpack values from objects or arrays into variables. Object destructuring: const { name, role } = user. Array destructuring: const [first, second] = arr. You can also rename: const { name: userName } = user and set defaults: const { role = "guest" } = user.
6 / 14
Sarah from the frontend team commented on your PR: 'This code relies heavily on `forEach`, which can be less performant than a more targeted approach. Consider using a `for...of` loop or perhaps even a higher-order function for better optimization.' Which of the following best reflects Sarah's feedback regarding performance optimization?
Sarah's comment highlights a crucial aspect of JavaScript performance. While `forEach` is often convenient, it can be less efficient than other looping constructs like `for...of` or higher-order functions (like `map`) when dealing with large datasets or complex operations. The key takeaway is that optimization choices should be driven by context and potential bottlenecks.
7 / 14
During the daily standup, you mentioned using a TypeScript interface to define the structure of your API response. You stated: 'The interface ensures that our backend team only returns data with these specific properties, preventing unexpected errors in our frontend.' Complete the sentence by filling in the blank: 'This practice is known as _____, and it improves type safety and reduces runtime errors.'
Structural typing is a core concept in TypeScript that focuses on matching the *shape* (properties and types) of interfaces rather than requiring identical implementations. This allows for greater flexibility while still maintaining type safety – it's about the 'contract' defined by the interface. The other options represent different programming paradigms, but don't directly address this specific aspect of TypeScript.
8 / 14
You're reviewing a PR that uses `async/await`. A developer included an `try...catch` block around each `await` call. Which of the following best explains why this approach is appropriate?
Using `try...catch` blocks around each `await` call in an `async/await` context is the recommended way to handle errors. This allows for targeted error handling – you can catch specific exceptions that might occur during the asynchronous operation and respond appropriately, rather than letting the entire program crash.
9 / 14
You're designing a TypeScript module to handle user authentication. You decide to use generics to create a type-safe function for retrieving user data from an API. The function signature is: `getUserData(userId: string): Promise`. What primary benefit does using generics in this scenario provide?
Generics provide powerful type safety. By specifying `T extends UserType`, you ensure that the data returned from the API *must* conform to the `UserType` interface or class – this prevents runtime errors caused by unexpected data shapes and improves code maintainability.
10 / 14
Sarah, a senior developer, just sent you this PR description: 'I'm using `Promise.all()` to fetch user data and product details concurrently. This should improve performance significantly.' You notice the code doesn't handle potential rejections from the promises. Which of the following is the MOST appropriate response to suggest?
Sarah's approach uses `Promise.all()`, which *does* inherently handle errors by rejecting the main promise if any of the inner promises reject. However, simply stating this isn't enough; Sarah needs to be aware that the code doesn't explicitly *catch* these rejections and handle them. Suggesting a `try...catch` block around `Promise.all()` is crucial for robust error handling. The other options represent misunderstandings about how `Promise.all()` works or incorrectly suggest unnecessary changes.
11 / 14
You're reviewing a TypeScript function that uses the Decorator syntax to automatically log method calls. The code looks clean but you're unsure if it will impact performance significantly. Which of the following is the BEST way to proceed?
While decorators *can* introduce overhead, it's crucial to verify this in a real-world scenario. Adding `console.time()` and `console.timeEnd()` around the decorated method call provides objective data about its performance impact. Simply trusting the decorator implementation isn't sufficient; and avoiding decorators entirely based solely on their nature is premature.
12 / 14
You're designing a TypeScript component that fetches data from an API. The API response includes nested objects and arrays. Which of the following is the MOST efficient way to access specific properties within these nested structures?
Destructuring is the most efficient and readable approach for accessing nested data in JavaScript/TypeScript. It avoids manually traversing the JSON structure with multiple `.` operators, which can be cumbersome and error-prone. `JSON.stringify()` is unnecessary; manual traversal is less efficient than destructuring. Flattening the entire object into a single array would drastically reduce readability and performance.
13 / 14
During a Slack conversation with your team, you see this message: 'I'm struggling to understand how TypeScript's type system can effectively handle asynchronous operations. It feels like I have to manually track all the states and potential errors.' Which of the following is the MOST helpful response you could provide?
The core issue is understanding how TypeScript's type system interacts with asynchronous operations. While `async/await` simplifies things, it's not a magical solution; developers still need to handle potential errors using techniques like `.then()` and `.catch()`. This response acknowledges the challenge and directs the team towards practical tools for managing async types.
14 / 14
You're writing a TypeScript function that processes an array of objects. The objects have a common property called `id` which you need to use for filtering and mapping. Which is the BEST approach to ensure type safety when working with this `id` property?
Defining a specific interface or type ensures that all objects passed into the function have an `id` property with a defined type (e.g., string or number). This eliminates potential runtime errors caused by missing or incorrectly typed properties. Using `Object.keys()` is less efficient and doesn't guarantee type safety.
What does the "JavaScript & TypeScript Vocabulary" vocabulary exercise cover?
This exercise tests real IT vocabulary related to javascript & typescript vocabulary through 14 multiple-choice questions, each built from realistic workplace sentences rather than abstract definitions.
Is this vocabulary exercise free to use?
Yes. Every exercise on CoderSlingo, including this one, is completely free — no account, sign-up, or payment required.
How many questions does this exercise have?
This exercise has 14 questions. Each one shows a real-world sentence or scenario with multiple-choice options and an explanation once you answer.
What happens after I answer a question?
You'll see immediate feedback showing whether your answer was correct, along with a short explanation of why — then a button to move to the next question, and a full results screen at the end.
Can I retry the exercise if I get questions wrong?
Yes. Once you reach the results screen, click "Try again" to reset your answers and go through the exercise from the start as many times as you like.
Do I need to create an account to take this exercise?
No account is needed. Your answers are scored in your browser during the session — nothing is saved to a server, so you can jump straight in.
Is my progress saved if I leave the page?
No — progress within an exercise resets if you navigate away or reload. Each exercise is short enough to complete in a few minutes in one sitting.
Are these vocabulary exercises connected to other topics?
Yes — this module shares real-world context with 2 other vocabulary modules. See "Related vocabulary" below to keep building a connected skill set.
How is this different from reading a glossary or blog article?
Exercises like this one are active recall drills — you have to choose the correct term or phrasing yourself, which builds retention faster than passively reading a definition.
Where can I find more vocabulary exercises?
Browse the full Vocabulary exercises hub for hundreds of modules covering Agile, DevOps, security, databases, architecture, and more — organised by IT role and skill.