Bird
Raised Fist0
Swiftprogramming~20 mins

Type erasure concept in Swift - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Swift Type Erasure Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of type-erased wrapper usage
What is the output of this Swift code using type erasure with AnySequence?
Swift
struct IntSequence: Sequence {
    func makeIterator() -> some IteratorProtocol {
        return (1...3).makeIterator()
    }
}

let seq: AnySequence<Int> = AnySequence(IntSequence())
for num in seq {
    print(num, terminator: " ")
}
A1 2 3
BSequence<Int>
CCompile-time error
D1 2 3 4
Attempts:
2 left
💡 Hint
Think about how AnySequence hides the underlying sequence type but still iterates correctly.
🧠 Conceptual
intermediate
1:30remaining
Purpose of type erasure in Swift
Why do Swift developers use type erasure?
ATo enable inheritance between unrelated classes
BTo hide concrete types and expose a common interface
CTo convert value types into reference types
DTo improve runtime performance by avoiding protocols
Attempts:
2 left
💡 Hint
Think about how protocols with associated types limit usage.
🔧 Debug
advanced
2:30remaining
Fix the error in this type erasure example
What error does this code produce and why? protocol Shape { associatedtype Color func draw() -> Color } struct AnyShape: Shape { private let _draw: () -> C init(_ shape: S) where S.Color == C { _draw = shape.draw } func draw() -> C { _draw() } } struct Circle: Shape { func draw() -> String { "Circle" } } let shape = AnyShape(Circle())
ANo error, code compiles successfully
BError: Cannot convert value of type 'Circle' to expected argument type 'Shape'
CError: Missing generic argument for 'AnyShape'
DError: 'Circle' does not conform to 'Shape' because 'Color' is not specified
Attempts:
2 left
💡 Hint
Check the associatedtype requirements in the protocol and the struct.
📝 Syntax
advanced
1:00remaining
Identify the syntax error in this type erasure wrapper
Which option correctly fixes the syntax error in this Swift type erasure code? struct AnyWrapper { private let _value: T init(_ value: T) { _value = value } func getValue() -> T { return _value } } let wrapper = AnyWrapper(5) print(wrapper.getValue()
AAdd a closing parenthesis after getValue(): print(wrapper.getValue())
BChange print to println: println(wrapper.getValue())
CAdd a semicolon after print: print(wrapper.getValue());
DReplace getValue() with getValue: print(wrapper.getValue)
Attempts:
2 left
💡 Hint
Check the parentheses balance in the print statement.
🚀 Application
expert
3:00remaining
How many elements does this type-erased sequence contain?
Consider this Swift code using type erasure. How many elements will be printed? struct EvenNumbers: Sequence { func makeIterator() -> some IteratorProtocol { (2...10).filter { $0 % 2 == 0 }.makeIterator() } } let numbers = AnySequence(EvenNumbers()) var count = 0 for _ in numbers { count += 1 } print(count)
A9
B0
C5
D10
Attempts:
2 left
💡 Hint
Count even numbers between 2 and 10 inclusive.

Practice

(1/5)
1. What is the main purpose of type erasure in Swift?
easy
A. To convert classes into structs automatically
B. To create new types from existing ones
C. To improve runtime performance by avoiding protocols
D. To hide specific types behind a common interface

Solution

  1. Step 1: Understand type erasure concept

    Type erasure is used to hide the concrete underlying type and expose a common interface.
  2. Step 2: Identify the main purpose

    This allows different types to be used uniformly without exposing their specific details.
  3. Final Answer:

    To hide specific types behind a common interface -> Option D
  4. Quick Check:

    Type erasure = hiding types behind interface [OK]
Hint: Type erasure hides types to unify usage [OK]
Common Mistakes:
  • Confusing type erasure with type conversion
  • Thinking it improves performance directly
  • Assuming it creates new types
2. Which of the following is the correct syntax to create a type-erased wrapper for a protocol MyProtocol?
easy
A. struct AnyMyProtocol: MyProtocol { private let _base: any MyProtocol }
B. struct AnyMyProtocol<T>: MyProtocol { private let _base: T }
C. struct AnyMyProtocol: MyProtocol { private let _base: MyProtocol }
D. struct AnyMyProtocol: MyProtocol { private let _base: some MyProtocol }

Solution

  1. Step 1: Recall type erasure syntax

    Type erasure uses a struct that conforms to the protocol and stores an instance of any Protocol to hide the concrete type.
  2. Step 2: Identify correct syntax

    struct AnyMyProtocol: MyProtocol { private let _base: any MyProtocol } uses any MyProtocol which is the correct way to store an existential type in Swift 5.7+.
  3. Final Answer:

    struct AnyMyProtocol: MyProtocol { private let _base: any MyProtocol } -> Option A
  4. Quick Check:

    Use any Protocol for type erasure storage [OK]
Hint: Use 'any Protocol' to store erased type [OK]
Common Mistakes:
  • Using generic parameter instead of existential
  • Using 'some Protocol' which is opaque, not erased
  • Trying to store protocol directly without 'any'
3. Consider this Swift code using type erasure:
protocol Shape {
    func area() -> Double
}

struct Circle: Shape {
    var radius: Double
    func area() -> Double { return .pi * radius * radius }
}

struct Square: Shape {
    var side: Double
    func area() -> Double { return side * side }
}

struct AnyShape: Shape {
    private let _area: () -> Double
    init(_ shape: S) {
        _area = shape.area
    }
    func area() -> Double { _area() }
}

let shapes: [AnyShape] = [AnyShape(Circle(radius: 2)), AnyShape(Square(side: 4))]
let totalArea = shapes.reduce(0) { $0 + $1.area() }
print(totalArea)
What is the output?
medium
A. 28.566370614359172
B. 13.141592653589793
C. Error: Cannot convert Circle to AnyShape
D. 0

Solution

  1. Step 1: Calculate area of Circle and Square

    Circle area = π * 2 * 2 = 12.566370614359172, Square area = 4 * 4 = 16
  2. Step 2: Sum areas in array

    Total area = 12.566370614359172 + 16 = 28.566370614359172
  3. Step 3: Check code output

    Code prints totalArea, which is 28.566370614359172
  4. Final Answer:

    28.566370614359172 -> Option A
  5. Quick Check:

    Sum of areas = 28.566370614359172 [OK]
Hint: Add areas of shapes wrapped in AnyShape [OK]
Common Mistakes:
  • Calculating area incorrectly
  • Confusing type erasure with type casting
  • Expecting compile error due to protocol
4. This Swift code attempts type erasure but causes a compile error:
protocol Printer {
    associatedtype Item
    func printItem(_ item: Item)
}

struct AnyPrinter: Printer {
    private let _print: (Any) -> Void
    init(_ printer: P) {
        _print = printer.printItem
    }
    func printItem(_ item: Any) {
        _print(item)
    }
}
What is the main cause of the error?
medium
A. Missing conformance to Printer protocol
B. Cannot assign generic method to closure with Any parameter
C. Cannot use associatedtype in protocol
D. Function printItem has wrong return type

Solution

  1. Step 1: Analyze closure assignment

    The closure _print expects (Any) -> Void but printer.printItem expects (P.Item) -> Void, which is a mismatch.
  2. Step 2: Understand type erasure limitation

    Associated types prevent direct assignment because the types differ; you cannot assign a generic method to a closure with Any parameter.
  3. Final Answer:

    Cannot assign generic method to closure with Any parameter -> Option B
  4. Quick Check:

    Generic method ≠ closure with Any parameter [OK]
Hint: Generic methods can't be assigned to Any closures directly [OK]
Common Mistakes:
  • Thinking protocol conformance is missing
  • Confusing associatedtype usage
  • Assuming return type mismatch
5. You want to create a type-erased wrapper for a protocol DataSource with an associated type Item and a method func fetch() -> [Item]. Which approach correctly applies type erasure to allow storing different DataSource implementations in a single array?
hard
A. Create a struct AnyDataSource with a private closure _fetch: () -> [Any] and cast results inside
B. Use a generic struct AnyDataSource<T> storing DataSource directly
C. Create a struct AnyDataSource with a private closure _fetch: () -> [Item] and use type erasure with a generic initializer
D. Use protocol inheritance to remove associated type

Solution

  1. Step 1: Understand associated type challenge

    Protocols with associated types cannot be used directly in collections because the type varies.
  2. Step 2: Apply type erasure pattern

    Create a struct with a private closure returning [Item], and initialize it generically to wrap any DataSource, hiding the concrete type.
  3. Step 3: Evaluate options

    Create a struct AnyDataSource with a private closure _fetch: () -> [Item] and use type erasure with a generic initializer correctly uses a generic initializer and closure with [Item], preserving type safety and enabling storage in arrays.
  4. Final Answer:

    Create a struct AnyDataSource with a private closure _fetch: () -> [Item] and use type erasure with a generic initializer -> Option C
  5. Quick Check:

    Type erasure with generic init and closure = Create a struct AnyDataSource with a private closure _fetch: () -> [Item] and use type erasure with a generic initializer [OK]
Hint: Use generic init and closure returning [Item] for erasure [OK]
Common Mistakes:
  • Casting to [Any] loses type safety
  • Using generic struct prevents uniform storage
  • Trying to remove associated type via inheritance
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