Unexpected behaviour when attempting to decode enum keys from a JSON dictionary

This first code works fine decoding json.

    static let localizationsDictText = """
{  "en" : {  "string" :  "Cat"   },
    "fr" : {  "string" : "Chat"}
}
"""
    struct Localization: Codable, Equatable {
        let string: String
    }
    typealias LocalizationsDict = [String: Localization]
    func testExample() throws {
        let text = Self.localizationsDictText
        let data = text.data(using: .utf8, allowLossyConversion: false)
        let localizationsDict = try JSONDecoder().decode(LocalizationsDict.self, from: data!)
        XCTAssertEqual(localizationsDict.keys.count, 2)
    }

But then I try to create a modified version of the above, only changing the type of the LocalizationsDict key from String to an enum:

    enum Language: String, CaseIterable, Codable {
        case en = "en"
        case fr = "fr"
    }
    typealias LocalizationsDict2 = [Language: Localization]
    
    func testExample2() throws {
        let text = Self.localizationsDictText
        let data = text.data(using: .utf8, allowLossyConversion: false)
        let localizationsDict = try JSONDecoder().decode(LocalizationsDict2.self, from: data!)
        XCTAssertEqual(localizationsDict.keys.count, 2)
    }

and the JSONDecoder line throws an exception: testExample2(): failed: caught error: "typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))"

Any suggestions as to why switching from [String: Localization] to [Language: Localization] might cause JSONDecode() to treat it like an array?

Thanks in advance for any guidance.

It seems to be a present limit (not to say bug) of Swift. When using a type different than String or Int as key to dictionary, dictionary is handled as an Array…

Get details here: https://stackoverflow.com/questions/44725202/swift-4-decodable-dictionary-with-enum-as-key

@mikeTheDad All you have to do is change

From the non codable type

typealias LocalizationsDict = [Language: Localization]

To the raw type of the enum and the decoding works.

typealias LocalizationsDict = [Language.RawValue: Localization]

Unexpected behaviour when attempting to decode enum keys from a JSON dictionary
 
 
Q