📖 Scenario: You are building a simple system to store and display information about different items. Each item must have a name property as a string. You want to create a generic class that can work with any item type, but only if it has a name property.
🎯 Goal: Create a generic class called ItemHolder that only accepts types with a name property of type string. Then, use this class to store an item and display its name.
📋 What You'll Learn
Create an interface called Named with a name property of type string
Create a generic class called ItemHolder with a type parameter constrained to Named
Add a constructor to ItemHolder that accepts an item of the generic type
Add a method getName that returns the name of the stored item
Create an object with a name property and use ItemHolder to hold it
Print the name of the stored item using the getName method
💡 Why This Matters
🌍 Real World
Generic classes with constraints help create reusable and safe code components that work with many types but enforce required properties.
💼 Career
Understanding generics and constraints is important for writing flexible and type-safe code in TypeScript, a skill valued in many software development roles.
Progress0 / 4 steps
1
Create the Named interface
Create an interface called Named with a single property name of type string.
Typescript
Hint
Use the interface keyword and define name: string inside.
2
Create the generic class ItemHolder with constraint
Create a generic class called ItemHolder with a type parameter T constrained to Named. Add a constructor that accepts a parameter item of type T and stores it in a public property called item.
Typescript
Hint
Use class ItemHolder<T extends Named> and a constructor with public item: T.
3
Add the getName method
Inside the ItemHolder class, add a method called getName that returns the name property of the stored item.
Typescript
Hint
Define getName() that returns this.item.name.
4
Create an item and print its name
Create a constant called myItem with a name property set to "Book". Then create an instance of ItemHolder called holder using myItem. Finally, print the result of holder.getName().
Typescript
Hint
Define myItem with name: "Book", create holder with new ItemHolder(myItem), then print holder.getName().
Practice
(1/5)
1. What is the main purpose of using constraints in a generic class in TypeScript?
easy
A. To ensure the generic type has specific properties or methods
B. To make the class run faster
C. To allow any type without restrictions
D. To convert the generic type to a string
Solution
Step 1: Understand generic constraints
Constraints limit the types that can be used with a generic to those having certain properties or methods.
Step 2: Identify the purpose of constraints
This ensures the generic class can safely use those properties or methods without errors.
Final Answer:
To ensure the generic type has specific properties or methods -> Option A
Quick Check:
Constraints = limit types by properties/methods [OK]
Hint: Constraints limit types to those with needed features [OK]
Common Mistakes:
Thinking constraints improve performance
Believing constraints allow any type
Confusing constraints with type conversion
2. Which of the following is the correct syntax to declare a generic class with a constraint that T must have a 'length' property?
T can be number or string, so value can be either type.
Step 2: Analyze method printValue()
It calls toFixed(2), which exists on number but not on string. TypeScript will produce a compile-time error because toFixed is not available on all possible types for T.
Final Answer:
toFixed is not available on string type -> Option A
Quick Check:
Method uses number-only function on union type [OK]
Hint: Check method compatibility with all constraint types [OK]
Common Mistakes:
Ignoring union type method availability
Thinking constraint syntax is wrong
Assuming missing return type causes error here
5. You want to create a generic class KeyValueStore that only accepts types with a key property of type string and a value property of any type. Which of the following is the correct way to declare this class?
hard
A. class KeyValueStore<T with key: string, value: any> { constructor(public item: T) {} }
B. class KeyValueStore<T> where T has key: string, value: any { constructor(public item: T) {} }
C. class KeyValueStore<T extends { key: string; value: any }> { constructor(public item: T) {} }
D. class KeyValueStore<T: { key: string; value: any }> { constructor(public item: T) {} }