Bird
Raised Fist0
Typescriptprogramming~20 mins

Generic constraints with extends in Typescript - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Generic Constraints Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of generic function with extends constraint
What is the output of the following TypeScript code?
Typescript
function getLength<T extends { length: number }>(arg: T): number {
  return arg.length;
}

console.log(getLength('hello'));
console.log(getLength([1, 2, 3]));
ATypeError at runtime
B5\n3
Chello\n[1,2,3]
DCompilation error
Attempts:
2 left
💡 Hint
Remember that both strings and arrays have a length property.
🧠 Conceptual
intermediate
1:30remaining
Understanding extends in generic constraints
Which statement best describes the role of extends in the generic constraint T extends { length: number }?
AIt restricts T to types that have a length property of type number.
BIt makes T inherit properties from a class named length.
CIt allows T to be any type without restrictions.
DIt forces T to be exactly the type { length: number }.
Attempts:
2 left
💡 Hint
Think about what types can be passed to a function requiring a length property.
🔧 Debug
advanced
2:30remaining
Identify the error in generic constraint usage
What error does this TypeScript code produce?
Typescript
function copyFields<T, U extends T>(target: T, source: U): T {
  for (const id in source) {
    target[id] = source[id];
  }
  return target;
}

const x = { a: 1, b: 2 };
const y = { a: 1, b: 3, c: 4 };
copyFields(x, y);
AError: Cannot assign to 'target[id]' because it is a constant.
BNo error, code runs fine.
CError: Type 'U' is not assignable to type 'T'.
DError: Property 'c' does not exist on type 'T'.
Attempts:
2 left
💡 Hint
Check the properties of the objects and the generic constraints.
📝 Syntax
advanced
2:00remaining
Correct generic constraint syntax
Which option correctly declares a generic function that accepts only objects with a name property of type string?
Afunction greet<T extends { name: string }>(obj: T): string { return `Hello, ${obj.name}`; }
Bfunction greet<T>(obj: T extends { name: string }): string { return `Hello, ${obj.name}`; }
Cfunction greet<T>(obj: T) where T has name: string { return `Hello, ${obj.name}`; }
Dfunction greet<T: { name: string }>(obj: T): string { return `Hello, ${obj.name}`; }
Attempts:
2 left
💡 Hint
Remember the correct syntax for generic constraints in TypeScript.
🚀 Application
expert
3:00remaining
Determine the output of complex generic constraint usage
What is the output of this TypeScript code?
Typescript
interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

const result = loggingIdentity({ length: 10, value: 3 });
console.log(result.value);
ACompilation error: Property 'value' does not exist on type 'T'.
B10\nundefined
C10\n3
DRuntime error: Cannot read property 'value' of undefined.
Attempts:
2 left
💡 Hint
Consider how TypeScript infers the type of the argument and the return value.

Practice

(1/5)
1.

What does the extends keyword do in a TypeScript generic constraint?

easy
A. It limits the generic type to types that match a specific shape or interface.
B. It makes the generic type optional.
C. It allows the generic type to be any type without restriction.
D. It converts the generic type to a string.

Solution

  1. Step 1: Understand the role of extends in generics

    The extends keyword in generics restricts the generic type to only those types that satisfy a certain condition, usually matching an interface or type shape.
  2. Step 2: Compare with other options

    Options B, C, and D describe behaviors unrelated to extends in generics. It does not make types optional, allow any type, or convert types to strings.
  3. Final Answer:

    It limits the generic type to types that match a specific shape or interface. -> Option A
  4. Quick Check:

    Generic constraints = limit type shape [OK]
Hint: Remember: extends restricts generic types to certain shapes [OK]
Common Mistakes:
  • Thinking extends makes a type optional
  • Confusing extends with type conversion
  • Assuming extends removes restrictions
2.

Which of the following is the correct syntax to constrain a generic type T to an object with a name property of type string?

function greet<T>(obj: T): string {
return `Hello, ${obj.name}`;
}
easy
A. function greet<T>(obj: T extends { name: string }): string
B. function greet<T extends { name: string }>(obj: T): string
C. function greet<T = { name: string }>(obj: T): string
D. function greet<T>(obj: T & { name: string }): string

Solution

  1. Step 1: Identify correct generic constraint syntax

    The correct way to constrain a generic type is using T extends { name: string } inside the angle brackets.
  2. Step 2: Check other options for syntax errors

    function greet<T = { name: string }>(obj: T): string uses assignment (=) which is for default types, not constraints. function greet<T>(obj: T extends { name: string }): string misplaces extends outside the angle brackets. function greet<T>(obj: T & { name: string }): string uses intersection (&) in parameter type, which is valid but not a generic constraint.
  3. Final Answer:

    function greet<T extends { name: string }>(obj: T): string -> Option B
  4. Quick Check:

    Use extends inside <> for constraints [OK]
Hint: Use extends inside <> for constraints [OK]
Common Mistakes:
  • Using = instead of extends for constraints
  • Placing extends outside generic brackets
  • Confusing intersection types with constraints
3.

What will be the output of this TypeScript code?

interface HasId { id: number; }
function getId<T extends HasId>(obj: T): number {
return obj.id;
}
const item = { id: 42, name: 'Book' };
console.log(getId(item));
medium
A. Error: Type argument does not satisfy constraint
B. undefined
C. Error: Property 'id' does not exist
D. 42

Solution

  1. Step 1: Check if item satisfies the constraint

    The interface HasId requires an id property of type number. The object item has id: 42, so it satisfies T extends HasId.
  2. Step 2: Understand function behavior

    The function returns obj.id, so calling getId(item) returns 42.
  3. Final Answer:

    42 -> Option D
  4. Quick Check:

    Object matches constraint, returns id [OK]
Hint: Check if argument matches constraint to predict output [OK]
Common Mistakes:
  • Assuming runtime error due to missing explicit type
  • Confusing property existence with type errors
  • Thinking generic constraints affect runtime output
4.

Identify the error in this TypeScript code and select the fix:

function printLength<T>(arg: T): number {
return arg.length;
}
medium
A. Add constraint: <T extends { length: number }>
B. Change return type to void
C. Remove length property access
D. Use any instead of generic T

Solution

  1. Step 1: Identify cause of error

    The generic type T has no guarantee to have a length property, so accessing arg.length causes a compile error.
  2. Step 2: Fix by adding a constraint

    Adding T extends { length: number } ensures arg has a length property, fixing the error.
  3. Final Answer:

    Add constraint: <T extends { length: number }> -> Option A
  4. Quick Check:

    Constraint ensures property exists [OK]
Hint: Add extends constraint to guarantee properties exist [OK]
Common Mistakes:
  • Ignoring missing property errors
  • Changing return type instead of fixing constraint
  • Using any defeats generic safety
5.

Given this interface and function, which call is valid and why?

interface Person {
name: string;
age: number;
}

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}

const person: Person = { name: 'Alice', age: 30 };

Which call is valid?

hard
A. getProperty(person, 0)
B. getProperty(person, 'height')
C. getProperty(person, 'name')
D. getProperty(person, 'toString')

Solution

  1. Step 1: Understand the generic constraints

    The function uses K extends keyof T, so the key must be a valid property name of T. For Person, valid keys are 'name' and 'age'.
  2. Step 2: Evaluate each option

    getProperty(person, 'name') uses 'name', which is a valid key. getProperty(person, 'height') uses 'height', not in Person. getProperty(person, 0) uses 0, not a key. getProperty(person, 'toString') uses 'toString', which is a method on Object prototype, not a key of Person interface.
  3. Final Answer:

    getProperty(person, 'name') -> Option C
  4. Quick Check:

    Key must be keyof object type [OK]
Hint: Use keys from interface only with keyof constraint [OK]
Common Mistakes:
  • Using keys not declared in interface
  • Passing numbers instead of string keys
  • Confusing prototype methods with interface keys
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard