Checking a type, obtained as a parameter: compiles in a 'dumb' way, but rejected in 'switch'

Classes Vc1 and Vc2 are subclasses of UIViewController:

class Vc1: UIViewController { .... }
class Vc2: UIViewController { .... }

The following code compiles without errors:

func onVCComplete(senderType: UIViewController.Type, details: Any) {

    if senderType == Vc1.self {
         /* ... */
    } 
    else
    if  senderType == Vc2.self {
        /* ... */
    } 
    else {
      fatalError("Unrecognised sender type: \(senderType)")
   }

However I find it more readable with switch statement:

func onVCComplete(senderType: UIViewController.Type, details: Any) {

    switch senderType {
        case Vc1.self: /* ...   */ 
    
        case Vc2.self: /* ... */

        default: fatalError("Unrecognised sender type: \(senderType)")
    }
}

This time I get compilation error: Expression pattern of type 'Vc1.Type' cannot match values of type 'UIViewController.Type'.

Tried Any.Type instead of UIController.Type - same error.

Is this supposed to be?

This thread belongs to "Using Swift" subforum.

But anyway, you can do it with 'is':

class Base {}

class Sub1: Base {}

class Sub2: Base {}

func doSwitch(myClass: Base.Type) {

switch myClass {

case is Sub1.Type: print("sub1")

case is Sub2.Type: print("sub2")

default : fatalError()

}

}

let sub1 = Sub1()
let sub2 = Sub2()
doSwitch(myClass: Sub1. self ) //prints "sub1"

2 Likes

The is syntax is certainly the preferred one when using a switch, but it'd be reasonable for the other syntax to work too. Can you file a bug at https://bugs.swift.org?

3 Likes