swiftswift-keypath

Key path value type 'Data.Element.ID' cannot be converted to contextual type 'ID'


I am getting the error Key path value type 'Data.Element.ID' cannot be converted to contextual type 'ID' when trying to create the initializer in the extension below for when the data which is passed contains elements which already inherit from Identifiable.

struct List<Data, ID> where Data: RandomAccessCollection, ID: Hashable {
    private let data: [Data.Element]
    private let id: KeyPath<Data.Element, ID>

    init(data: Data, id: KeyPath<Data.Element, ID>) {
        self.data = data.map { $0 }
        self.id = id
    }
}

extension List where Data.Element: Identifiable {
    init(data: Data) {
        self.data = data.map { $0 }
        self.id = \Data.Element.id // Compilation Error: Key path value type 'Data.Element.ID' cannot be converted to contextual type 'ID'
    }
}

Solution

  • Data.Element.ID isn't guaranteed to be of type List.ID. You can fix this by adding another type type constraint.

    extension List where Data.Element: Identifiable, Data.Element.ID == ID {
        init(data: Data) {
            self.data = data.map { $0 }
            self.id = \.id
        }
    }