Typealias

I have a hierarchy of protocols and related, nested type implementations that resolve to the same class. In the sample I get an compiler error
Cannot convert value of type [FactoryType.AssetInstanceType] to expected argument type [FactoryType.AssetType.InstanceType] ( in this case, both alias SomeAssetInstance)

How can I fix it?

import Foundation

// Protocols:
protocol AssetInstance : class {
    var identifier: String { get set }
}

protocol Asset : class {
    associatedtype InstanceType : AssetInstance
    var identifier: String { get set }
    var instances: [InstanceType] { get set }
}

protocol AssetFactory {
    associatedtype AssetType : Asset
    associatedtype AssetInstanceType : AssetInstance

    func createAsset() -> AssetType
    func createInstance() -> AssetInstanceType

    func allAssets() -> [AssetType]
    func allInstances() -> [AssetInstanceType]
}

// implementations:

class SomeAssetInstance : AssetInstance {
    var identifier = ""
}

class SomeAsset : Asset {
    typealias InstanceType = SomeAssetInstance
    var identifier = ""
    var instances = [SomeAssetInstance]()
}

class SomeFactory : AssetFactory {
    typealias Asset = SomeAsset
    typealias AssetInstance = SomeAsset.InstanceType

    private var assets = [Asset]()
    private var instances = [AssetInstance]()

    func createAsset() -> Asset {
        let r = Asset()
        assets.append( r )
        return r
    }

    func createInstance() -> AssetInstance {
        let r = AssetInstance()
        instances.append( r )
        return r
    }

    func allAssets() -> [Asset] {
        return assets
    }

    func allInstances() -> [AssetInstance] {
        return instances
    }
}

// Generic algo using the PAT hierarchy above
class SomeManager<FactoryType : AssetFactory> {
    typealias AssetType =         FactoryType.AssetType
    typealias AssetInstanceType = FactoryType.AssetType.InstanceType

    let factory : FactoryType

    required init( _ factory: FactoryType ) {
        self.factory = factory
    }

    func doSomething( _ newInstances : [AssetInstanceType] ) {
        // ERROR HERE:
        // Cannot convert value of type [FactoryType.AssetInstanceType] to expected arguemt type [FactoryType.AssetType.instanceType]
        merge( existing: factory.allInstances() )
    }

    func merge( existing: [AssetInstanceType] )  {

    }
}

let m = SomeManager( SomeFactory() )
let instances = [ SomeAssetInstance() ]
m.doSomething( instances )

Factory protocol should be declared like this:

protocol AssetFactory {
    associatedtype AssetType : Asset where AssetType.InstanceType == AssetInstanceType
    associatedtype AssetInstanceType

    func createAsset() -> AssetType
    func createInstance() -> AssetInstanceType

    func allAssets() -> [AssetType]
    func allInstances() -> [AssetInstanceType]
}
1 Like
Terms of Service

Privacy Policy

Cookie Policy