title: Switch over the generic type in a generic class in Swift
body: <p>I've recently tried to write an extension for the <a href="https://developer.apple.com/reference/foundation/measurement" rel="nofollow noreferrer"><code>Measurement</code></a> type in iOS 10 which <strong>switch-cases over the type of the generic</strong> <code>UnitType</code>. What I wanted to do is to specify a different string output on a <code>UILabel</code> based on the type of unit. My goal was to <strong>simplify the usage</strong>.</p>
  
  <p>The <strong>solution</strong> I came up with was to <strong>define a method for every type of generic</strong> like so:</p>
  
  <pre><code>func localizedDescription(for length: Measurement&lt;UnitLength&gt;) -&gt; String {
      // some code
  }
  
  func localizedDescription(for speed: Measurement&lt;UnitSpeed&gt;) -&gt; String {
      // some code
  }
  
  // etc.
  </code></pre>
  
  <p>What I really wanted was <strong>something different</strong> though, but I couldn't get it to work. Maybe you can, or it is a restriction of Swift as of now. I've prepared a Swift Playground to explain this in detail.</p>
  
  <h2>Example Playground Code</h2>
  
  <p>Here's the code that should replicate the situation:</p>
  
  <pre><code>import Foundation
  
  //: Example Classes
  
  class GenericType: NSObject {
      // some code
  
      var value: Double {
          preconditionFailure("Must be overridden in subclasses.")
      }
  }
  class GenericSubType1: GenericType {
      override var value: Double { return 5 }
  }
  class GenericSubType2: GenericType {
      override var value: Double { return 10 }
  }
  
  // Note that the class is predefined in a different place, so I can't use the body directly.
  class SomeClass&lt;T: GenericType&gt; {
      var valueType: T
      init(valueType: T) {
          self.valueType = valueType
      }
  }
  </code></pre>
  
  <h3>Switch-Case Extension</h3>
  
  <p>Here's my first <strong>approach using a switch-case</strong>:</p>
  
  <pre><code>//: Switch-Case in Extension
  
  extension SomeClass {
      var localizedDescription: String {
          switch T.self { // `type(of: T)` doesn't work, `T` does neither
          case is GenericSubType1:
              return "\(valueType.value) times"
  
          case is GenericSubType2:
              return "\(valueType.value) people"
  
          default:
              preconditionFailure("Forgot to define a description for generic subclass: \(T.self).")
          }
      }
  }
  </code></pre>
  
  <p>I'm getting a <strong>warning</strong> though in the two <code>case</code> lines which states:</p>
  
  <blockquote>
    <p>Cast from 'T.Type' to unrelated type 'GenericSubType1' always fails</p>
  </blockquote>
  
  <p>I'm not sure why this is giving me this warning, I'd expect this to work as expected. Can somebody explain me? And also, how would you best solve this kind of thing?</p>