Skip to content
tezvyn:

Top 30 Generics Interview Questions and Answers

30 multiple-choice questions on Generics, drawn from 30 bites out of the 50 tagged Generics on Tezvyn. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.

30 questions. Pick an answer, or open “Show the answer” to read it.

Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.

  1. Question 1 of 30

    Which getProperty signature both rejects invalid keys at compile time and returns the exact type of the requested property?

    Show the answer

    Answer: c · Two generics T and K where K extends keyof T and the return type is T[K]

    Option C is correct because constraining K with extends keyof T limits keys to valid properties on T, while T[K] preserves the exact type of the accessed property. Option D is tempting because keyof T does restrict keys, but T[keyof T] produces a union of all property types rather than the specific one for the key passed.

    Read the full bite: Create a generic getProperty using generics and keyof

  2. Question 2 of 30

    What is the primary benefit of defining a Rust trait, such as Summary with a summarize method, and implementing it for multiple distinct types?

    Show the answer

    Answer: b · It allows writing generic functions that can operate on any type that fulfills the Summary contract, promoting code reuse.

    The card states traits enable "writing generic functions that can accept any type that fulfills a certain contract," which directly leads to code reuse and abstraction. Option D is a tempting distractor because traits can have default implementations, but the primary benefit isn't the automatic provision of a default, but rather the ability to treat different types uniformly based on their shared behavior.

    Read the full bite: Rust Traits: Defining Shared Behavior

  3. Question 3 of 30

    When writing a swap function in Swift, what advantage does using a generic placeholder T provide over accepting parameters of type Any?

    Show the answer

    Answer: d · Generics enforce that both parameters are the same concrete type and avoid runtime casting

    Generics preserve compile-time type information, ensuring both arguments share the same type and eliminating unsafe downcasting. Distractor A is tempting because Any permits heterogeneous values, but a generic swap<T> explicitly prevents mixing types, which is exactly why it is type-safe.

    Read the full bite: What are Swift generics, why useful, and write a swap function?

  4. Question 4 of 30

    What primary problem do Dart generics address in software development?

    Show the answer

    Answer: b · Allowing code to operate on different data types without sacrificing compile-time type safety.

    Generics solve the problem of writing code that works with various data types while maintaining type safety at compile time, preventing errors that would arise from using less specific types like Object or dynamic. Option A is incorrect because generics enforce type safety at compile-time, which is distinct from dynamic typing that defers type checking to runtime.

    Read the full bite: Dart Generics: Type-Safe Containers and Reusable Code

  5. Question 5 of 30

    What is the primary reason to use an associated type within a Swift protocol?

    Show the answer

    Answer: b · To enable the protocol to refer to a type whose concrete definition is only known by conforming types.

    Associated types exist to allow a protocol's blueprint to refer to a type that is not known until a concrete type adopts the protocol, making the protocol generic over types it uses. Option C is a tempting distractor because, while desirable, the card explicitly states that protocols with associated types cannot be used directly as concrete types for variables or collections without workarounds.

    Read the full bite: Associated Types: Making Protocols Generic

  6. Question 6 of 30

    What is the primary implication of declaring a generic type parameter with the `out` modifier, as in `interface Source<out T>`?

    Show the answer

    Answer: b · It allows an instance of `Source<String>` to be used where `Source<Any>` is expected.

    The `out` modifier indicates covariance (a producer), which preserves the subtyping relationship. This allows a `Source<subtype>` (like `String`) to be used as a `Source<supertype>` (like `Any`). A common misconception is that `out` implies immutability, but it only enforces type safety.

    Read the full bite: Explain Kotlin's declaration-site variance with `in` and `out`

  7. Question 7 of 30

    What is the primary type-system benefit of declaring an interface as Producer<out T> when T only appears in return positions?

    Show the answer

    Answer: b · It lets Producer<String> be used where Producer<Any> is expected without caller-side wildcards.

    Marking T with out makes Producer covariant, so Producer<String> is a subtype of Producer<Any> and callers never need wildcards. Option C is wrong because variance does not imply immutability; the class may still mutate state via operations that do not mention T.

    Read the full bite: Explain Kotlin's declaration-site variance with in and out

  8. Question 8 of 30

    To maximize type flexibility for a generic interface DataSink<T> that exclusively consumes elements of type T, which variance modifier should be used?

    Show the answer

    Answer: b · in T

    The 'in' modifier is used for contravariant types that act as consumers, allowing a supertype (e.g., DataSink<Any>) to be used where a subtype (e.g., DataSink<String>) is expected, thus maximizing flexibility. The 'out' modifier is for producers, which would be incorrect for a consumer interface.

    Read the full bite: Explain Kotlin's declaration-site variance with in and out

  9. Question 9 of 30

    What is the fundamental reason Kotlin's `reified` type parameters must be used with `inline` functions?

    Show the answer

    Answer: b · The inline mechanism enables the compiler to replace the generic type parameter with the actual type at the call site before JVM type erasure occurs.

    Correct answer (B) states that `inline` allows the compiler to substitute the generic type with its concrete type at the call site, effectively baking the type information into the bytecode before JVM type erasure. Option C is incorrect because `reified` does not bypass JVM type erasure; instead, the compiler works around it by substituting the type during inlining.

    Read the full bite: Explain Kotlin's `reified` type parameters and their use case

  10. Question 10 of 30

    Why can a reified type parameter be checked with is T at runtime despite JVM type erasure?

    Show the answer

    Answer: c · The compiler substitutes the concrete type into the inlined body at each call site.

    Inline expansion lets the compiler replace T with the concrete type at the call site, emitting a real instanceof check. Option A is tempting but wrong because reified does not rely on reflection or pass a Class object; it works by bytecode substitution during compilation.

    Read the full bite: What is a reified type parameter in Kotlin?

  11. Question 11 of 30

    What is the core mechanism that allows a `reified` type parameter to be accessible at runtime in a Kotlin `inline` function?

    Show the answer

    Answer: a · The compiler copies the function's body and the actual type argument directly into the location where the function is called.

    `reified` works because the `inline` function's body and its actual type arguments are copied directly to the call site by the compiler, thus avoiding type erasure. Option D describes a common manual workaround for type erasure, not the automated mechanism of `reified`.

    Read the full bite: What is a reified type parameter in Kotlin?

  12. Question 12 of 30

    Which approach correctly gives a polymorphic Typography component type-safe props so that disabled is rejected when as is h1 but to is accepted when as is a custom Link?

    Show the answer

    Answer: d · constrain the generic C to React.ElementType and intersect Omit<ComponentPropsWithoutRef<C>, 'color'> with the component's own props

    Option D is correct because React.ElementType accepts both intrinsic tags and custom components, ComponentPropsWithoutRef<C> surfaces the correct props for each C, and Omit resolves clashes with custom APIs like color. Option A is tempting but excludes custom components such as Link, while A and D sacrifice compile-time validation.

    Read the full bite: Design a type-safe polymorphic component that renders as different HTML elements

  13. Question 13 of 30

    Which TypeScript structure should you choose to make an ApiResponse<T> that cannot simultaneously hold both data and error properties?

    Show the answer

    Answer: d · A union of two interfaces sharing a status literal, one generic branch with data: T and the other with error: { code; message; }

    A discriminated union with a shared literal status makes it impossible to represent both states at once and enables automatic type narrowing. Option A is a common mistake because optional fields and a broad string status allow objects where both data and error are present, absent, or mismatched.

    Read the full bite: Write a generic ApiResponse<T> type with success and error states

  14. Question 14 of 30

    What is the primary reason Kotlin's MutableList<E> is invariant, while List<out E> is covariant?

    Show the answer

    Answer: b · MutableList allows elements of type E to be both added to and retrieved from the list, requiring E to be used in both 'in' and 'out' positions.

    The card explains that a generic type must remain invariant if it is used in both 'in' (consumer, like add) and 'out' (producer, like get) positions, which is precisely the case for MutableList. Option A is tempting because mutability is the context, but the direct reason for invariance is the dual usage of the generic type in 'in' and 'out' positions, as per Kotlin's variance rules.

    Read the full bite: Kotlin's `in` and `out`: Declaration-Site Variance

  15. Question 15 of 30

    What is the fundamental reason Kotlin's reified type parameters are exclusively usable with inline functions?

    Show the answer

    Answer: c · The compiler uses inline functions to substitute the actual type argument directly into the function's bytecode at the call site.

    The card states that when an inline function is called, the compiler copies its body to the call site and replaces the reified generic type with the actual type argument. This compile-time substitution is the core mechanism that inline functions enable for reified types. Option B describes a workaround that reified types aim to eliminate, not how they function with inline.

    Read the full bite: Reified Type Parameters: Accessing Generic Types at Runtime

  16. Question 16 of 30

    What return type does fetchItem<T extends boolean>(..., includeHistory: T): T extends true ? ExtendedItem : BaseItem yield when includeHistory is a plain boolean variable?

    Show the answer

    Answer: c · The type resolves to ExtendedItem | BaseItem because boolean encompasses both true and false

    Because boolean is equivalent to true | false, the distributive conditional type evaluates both branches and produces a union. Option B is tempting but wrong because TypeScript does not narrow a plain boolean variable to a literal across a function boundary.

    Read the full bite: How would you model fetchItem's return type with generics and conditional types?

  17. Question 17 of 30

    Given a type `Mapish = { [k: string]: boolean; }`, what type does `keyof Mapish` evaluate to?

    Show the answer

    Answer: d · string | number

    The card explicitly states that for a string index signature like `{ [k: string]: boolean; }`, `keyof Mapish` evaluates to `string | number`. This is due to JavaScript's runtime behavior where numeric keys are coerced to strings, which TypeScript reflects for safety. Simply `string` would be incorrect as it omits the numeric access possibility.

    Read the full bite: keyof: A Union Type of an Object's Keys

  18. Question 18 of 30

    What is the most significant problem that TypeScript Conditional Types are designed to solve in generic programming?

    Show the answer

    Answer: b · Enabling a single generic function to have a return type that adapts based on its input type, reducing the need for multiple overloads.

    The card highlights that conditional types are used to model the relationship between input and output types, specifically to avoid an 'explosion of function overloads' by allowing a single generic function's return type to be dynamic. Option D is incorrect because conditional types are a compile-time construct, not a runtime mechanism for type changes.

    Read the full bite: Conditional Types: Ternary Logic for Your Types

  19. Question 19 of 30

    When building a single TypeScript handler for mixed form inputs, which strategy correctly preserves type safety when extracting values from checkboxes, text inputs, and selects?

    Show the answer

    Answer: b · Narrow event.target with instanceof checks and branch on element.type to read .checked or .value.

    Narrowing with instanceof and branching on element.type lets the compiler verify you read .checked for checkboxes and .value for other elements. Option D is tempting because it uses a union type, but reading .value from a checkbox gives the string on rather than the boolean state, breaking both type safety and runtime logic.

    Read the full bite: Write a generic TypeScript handler for mixed form inputs?

  20. Question 20 of 30

    When a nil pointer is boxed into an interface{}, why does a subsequent nil check on that interface return false?

    Show the answer

    Answer: b · The interface value carries type information, so it is not nil

    An interface{} holding a nil pointer is non-nil because it stores dynamic type metadata alongside the data pointer. Distractor D is wrong because a bare type assertion panics only when the dynamic type does not match, not when the underlying concrete value is nil.

    Read the full bite: Explain Go's empty interface, safe usage, and runtime risks

  21. Question 21 of 30

    Why does the standard library make Item an associated type on Iterator rather than a generic parameter Iterator<Item>?

    Show the answer

    Answer: d · Because a type yields exactly one element type, so associated types keep next() inference unambiguous

    Each iterator produces one element type, so an associated type uniquely determines Item and next() infers without annotation. The last option is backwards: generics, not associated types, would allow multiple impls.

    Read the full bite: Associated types vs generic type parameters in traits

  22. Question 22 of 30

    In a generic fetchJson wrapper, why is it critical to check response.ok before returning res.json() as Promise<T>?

    Show the answer

    Answer: d · Because fetch resolves even on 4xx/5xx statuses, so skipping the check would return an error payload incorrectly typed as T.

    fetch resolves successfully on HTTP error codes such as 404 or 500, so without the ok guard the caller would receive an error body wrongly typed as T. Option A is a tempting misconception because fetch only rejects on network failures, not on HTTP error statuses.

    Read the full bite: Create a generic fetchJson wrapper with typed response and error handling

  23. Question 23 of 30

    Which TypeScript signature correctly refactors firstElement to preserve the array's element type while returning a single element?

    Show the answer

    Answer: c · function firstElement<T>(arr: T[]): T

    Using T[] as the return type is a tempting mistake because it keeps the array wrapper instead of extracting the element, while any and unknown erase the specific type information entirely.

    Read the full bite: Refactor a function using generics to accept any array type

  24. Question 24 of 30

    Which TypeScript signature preserves the specific input type while safely allowing access to a length property in a generic utility function?

    Show the answer

    Answer: a · function logLength<T extends { length: number }>(arg: T): T { console.log(arg.length); return arg; }

    Option A constrains T with extends so the compiler knows length exists, yet returns T to keep the exact input type. Option B is tempting because it references the same shape, but it widens the return type and erases the original identity of arrays, strings, or custom objects.

    Read the full bite: Explain generic constraints and provide a length-constrained generic example

  25. Question 25 of 30

    In getProperty<T, K extends keyof T>(obj: T, key: K), what is the effect of changing the return type from T[K] to T[keyof T]?

    Show the answer

    Answer: c · The return type widens to a union of all property types in T instead of the specific type for the provided key.

    T[K] looks up the exact type for the specific key passed, whereas T[keyof T] resolves to a union of every property type on T because keyof T is a union of all keys. The most tempting distractor is wrong because key validation still happens at the parameter level via K extends keyof T, regardless of what the return type uses.

    Read the full bite: Write a generic type-safe getProperty using keyof

  26. Question 26 of 30

    What is the main risk of declaring separate generic parameters on getState and setState instead of one class-level T?

    Show the answer

    Answer: b · The methods could be invoked with unrelated types, so getState and setState no longer agree on the state type.

    A class-level generic binds every method to the same concrete type after instantiation, but method-level generics let getState and setState operate on unrelated types, breaking state consistency. Distractor A describes a different mistake—forgetting to type the constructor argument—not the specific consequence of scattering generics across methods.

    Read the full bite: Create a generic State class with getState and setState

  27. Question 27 of 30

    What is the main type-safety benefit of making fetchJSON generic with <T> rather than having it return Promise<any>?

    Show the answer

    Answer: c · It lets the caller decide the expected response shape for compile-time checking without changing the wrapper code.

    The generic T is supplied by the caller, allowing compile-time type checking and autocomplete without hardcoding shapes in the wrapper. C is wrong because TypeScript generics are erased at compile time and never perform runtime validation.

    Read the full bite: Write a generic fetchJSON<T> wrapper and explain its type safety benefits

  28. Question 28 of 30

    Using function merge<T, U>(a: T, b: U): T & U { return { ...a, ...b }; }, what is the runtime value of a key present in both objects?

    Show the answer

    Answer: b · The value from b, since b is spread last and overwrites a's key

    Object spread applies properties left to right, so b's value overwrites a's for shared keys at runtime. The intersection type does not merge values, and overlapping keys do not cause a compile error here.

    Read the full bite: Generic merge with an intersection return type

  29. Question 29 of 30

    What is the primary type-system purpose of resolving to never in the false branch of MyReturnType<T>?

    Show the answer

    Answer: d · It prevents non-function types from being silently assignable by making invalid usages immediately unassignable

    The never branch preserves type safety by ensuring non-function types produce an unassignable type, which stops invalid usage at compile time. Leaving the false branch as T or unknown would silently allow non-functions to pass through, a common mistake.

    Read the full bite: Implement MyReturnType<T> using conditional types and infer

  30. Question 30 of 30

    What is the primary advantage of using TypeScript generics?

    Show the answer

    Answer: c · It enables the creation of reusable components that maintain type safety across different data types.

    Generics are designed to create components that are both reusable across various data types and type-safe, ensuring type information flows from input to output. Option B describes the 'any' type, which sacrifices type safety, while generics preserve it.

    Read the full bite: TypeScript Generics: Writing Functions That Adapt to Types

Could you explain these out loud?

That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon