Contents

jhonatn/swifttypefamily

### Before anything...

How do I include in my project?

This is a Swift Package. Check your project's Package Dependencies in case you're using a Xcode Project/Workspace, or your Package.swift file if you're writing a Swift Package. Xcode will request you to enable Macro expansion for TypeAlias. This is what makes the compiler generate code, so enable it. Also, some versions of Xcode seem to need a restart (Close Xcode fully, open Xcode again) before picking up on macros.

Using it

First, you declare the parent type. This will always be an enum, and have the macro @TypeFamily at the start of it.

@TypeFamily
enum ExampleParent {

}

The compiler will request from you to specifiy a type for the children to share between them, under the type alias TypeChild

protocol ExampleProtocol {
    var aMethodThatAllChilrenHave: Bool { get }
}
@TypeFamily
enum ExampleParent {
    typealias TypeChild = ExampleProtocol
}

Now you can add any child type you need. The child type will need to be declared inside the parent type, to inherit/conform to TypeChild and have the macro @TypeFamilyChild.

// ...
    @TypeFamilyChild
    struct ExampleChild: TypeChild {
        let aMethodThatAllChilrenHave: Bool
        let somethingOnlyThisChildHas: Int
    }
// ...

... and that's it!

What the macros generate:

  • An enum case for each type you add based on the name of the type.

``swift case exampleChild(ExampleChild) ` If you want to customize the case name, you can add a String to the @TypeFamilyChild parameters `swift @TypeFamilyChild("customEnumCaseName") // This generates customEnumCaseName(ExampleChild) ``

  • A computed property for the enum that returns the object inside any case, type-erased to any TypeChild

``swift var childValue: any TypeChild // ... let exampleParent = ExampleParent.exampleChild(.init(/ ... /)) print(exampleParent.childValue.aMethodThatAllChilrenHave) ` You can also specify the option .keyPathed to @TypeFamily, together with @dynamicMemberLookup, to be able to use child properties directly from its parent `swift @TypeFamily(.keyPathed) @dynamicMemberLookup enum ExampleParent { // ... let exampleParent = ExampleParent.exampleChild(.init(/ ... /)) print(exampleParent.aMethodThatAllChilrenHave) ``

  • A method for the child object to be converted back to its parent type

``swift let exampleParent = ExampleParent.exampleChild(.init(/ ... /)) let child = exampleParent.childValue let anotherParent = ExampleParent.wrapping(child) // Same as exampleParent ``

Package Metadata

Repository: jhonatn/swifttypefamily

Default branch: main

README: README.md