Q:

Objc-C to Swift: How to create a property in Swift that guarantees it's of a certain type when callers use it?

TL;DR: This is about migrating an Objective-C pattern to Swift. It might be best to first look at the Objective-C interface below to better understand what I'm trying to achieve.
I am just starting to adapt a rather large codebase from Objective-C to Swift. There were some design patterns in the legacy codebase that were put in place to try and provide some type-safety. 
These patterns seem really out of place in Swift but I'm not sure what the proper "Swift Way" of doing this is. Using Generics feels like the way to go about it, but I'm unclear on how best to proceed. 
The goal is to create a struct that has a property that can hold "almost anything". Callers are expecting the property to be of a certain type when used and an error or exception should be thrown if there is a type-mismatch. (i.e.: The caller expected the argument to be an integer but in reality a string was store.) 
struct Command<T> {
  let directive: Directive
  let argument: T
}

let command = Command(directive: .draw, argument: NSZeroRect)
let command2 = Command(directive: .toggle, argument: true)

// Somewhere else in the code...

//
// How do I pass in a Command<> here? 
// This generates an error because Command<Bool> cannot be converted to Command<Any>
//
func processCommand(_ command:Command<Any>) {
  switch command.directive {
  case .draw:
    // How do I ensure that command.argument is indeed an NSRect?
  case .toggle:
    // How do I ensure that command.argument is indeed a boolean?
  }
}

The Objective-C interface looks something like this. Note that argument can be many different types. Ranging from primitives (Integers, Booleans, Doubles, etc...) to anything that can be stored in NSValue or that supports NSCoding. 
There are multiple property accessors for each type where it makes sense. 
@interface FLCommand : NSObject

@property(assign, readonly) FLDirective directive;
@property(strong, readonly) id argument;

@property(strong, readonly) BOOL argumentAsBoolean;
@property(strong, readonly) NSRect argumentAsRect;

- (instancetype)initWithDirective:(FLDirective)directive booleanArgument:(BOOL)value;
- (instancetype)initWithDirective:(FLDirective)directive rectArgument:(NSRect)rect;
- (instancetype)initWithDirective:(FLDirective)directive argument:(id)arg;

@end

@implementation FLCommand

- (instancetype)initWithDirective:(FLDirective)directive
                     booleanValue:(BOOL)value {

  // Convert boolean to object.
  return [self initWithDirective:directive 
                        argument:@(value)];
}

- (instancetype)initWithDirective:(FLDirective)directive
                     rectArgument:(NSRect)rect {

  // Convert NSRect to object.
  return [self initWithDirective:directive 
                        argument:[NSValue valueWithRect:rect]];
}

- (BOOL)argumentAsBoolean {
    NSAssert([_argument isKindOfClass:NSNumber.class], @"Expected argument to be an NSNumber.");

    return [self.argument boolValue];
}

- (NSRect)argumentAsRect {
    NSAssert([_argument isKindOfClass:NSValue.class], @"Expected command argument to be an NSValue.");

    return [(NSValue *)self.argument rectValue];
}

@end

// Somewhere else in the code the commands are acted upon. Using the 
// asserts and type-specific property accessors offers a poor-man's 
// way of doing type safety to ensure the the command's argument is 
// of the expected type.

- (void)processCommand:(FLCommand *)command {
    switch (command.directive) {
        case FLDirectiveToggleSomething:
                // The assert will fire if the argument is not a boolean.
                [self toggleSomething:command.argumentAsBoolean];
            break;

            case FLDirectiveDrawSomething:
                [self drawSomethingInFrame:command.argumentAsRect];
            break;
        }
    }
}

Using an equivalent pattern in Swift seems very un-Swift like to me. Is there a better way to go about this using Generics? 
Swift 5 and macOS 10.15+ solutions are OK.

A:

Have you considered using enumerations with associated values (often referred to as complex enums)
enum Directive {
    case draw(NSRect)
    case toggle(Bool)
}

struct Command {
    let directive: Directive
}

let command = Command(directive: .draw(.zero))
let command2 = Command(directive: .toggle(true))

func processCommand(_ command: Command) {
    switch command.directive {
    case .draw(let rect):
        // do something with rect
    case .toggle(let value):
        // do something with the value
    }
}

(And you could actually skip the Command struct entirely in the above)
Or an alternative solution is to use a protocol with an associated type:
protocol Command {
    associatedtype AssociatedType

    var argument: AssociatedType { get }

    init(_ argument: AssociatedType)

    func process()
}

struct DrawCommand: Command {
    typealias AssociatedType = NSRect
    let argument: AssociatedType

    init(_ argument: AssociatedType) {
        self.argument = argument
    }

    func process() {
        print("draw something with \(argument)")
    }
}

struct ToggleCommand: Command {
    typealias AssociatedType = Bool
    let argument: AssociatedType

    init(_ argument: AssociatedType) {
        self.argument = argument
    }

    func process() {
        print("toggle something with \(argument)")
    }
}

let command = DrawCommand(.zero)
let command2 = ToggleCommand(true)

command.process()
command2.process()

This have a bit more boilerplate/overload, but provides a better separation of concerns and will be more flexible for you introducing more commands in the future without having to update enum/switches multiple places in the code.

