# A heterogeneous dictionary with strong types in Swift

DevFeed: [A heterogeneous dictionary with strong types in Swift](<https://devfeed.tech/articles/a-heterogeneous-dictionary-with-strong-types-in-swift-21712.md>)

Original publisher: [Read original article](<https://oleb.net/2022/heterogeneous-dictionary/>)

Author: Ole Begemann

Published: 2022-04-19T15:52:08Z

Content type: tutorial

Language: en

Sources: [Ole Begemann](<https://devfeed.tech/sources/ole-begemann.md>)

Topics: [Swift](<https://devfeed.tech/topics/swift.md>), [SwiftUI](<https://devfeed.tech/topics/swiftui.md>), [Code](<https://devfeed.tech/topics/code.md>), [Protocol (disambiguation)](<https://devfeed.tech/topics/protocol.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [protocol](<https://devfeed.tech/tags/protocol.md>), [swift](<https://devfeed.tech/tags/swift.md>), [swiftui](<https://devfeed.tech/tags/swiftui.md>)

## AI overview

This article presents a type-safe heterogeneous dictionary in Swift, modeled partly on the SwiftUI environment. Each type-based key is associated with a specific value type, allowing mixed key-value pairs without casting. The design uses domains or keyspaces to restrict which keys belong to a dictionary.

## Source excerpt

The environment in SwiftUI is sort of like a global dictionary but with stronger types: each key (represented by a key path) can have its own specific value type. For example, the \.isEnabled key stores a boolean value, whereas the \.font key stores an Optional<Font>. I wrote a custom dictionary type that can do the same thing. The HeterogeneousDictionary struct I show in this article stores mixed key-value pairs where each key defines the type of value it stores. The public API is fully type-safe, no casting required. Usage I'll start with an example of the finished API. Here's a dictionary for storing text formatting attributes: import AppKit var dict = HeterogeneousDictionary<TextAttributes>() dict[ForegroundColor.self] // -> nil // The value type of this key is NSColor dict[ForegroundColor.self] = NSColor.systemRed dict[ForegroundColor.self] // -> NSColor.systemRed dict[FontSize.self] // -> nil // The value type of this key is Double dict[FontSize.self] = 24 dict[FontSize.self] // -> 24 (type: Optional<Double>) We also need some boilerplate to define the set of keys and their associated value types. The code to do this for three keys (font, font size, foreground color) looks like this: // The domain (aka "keyspace") enum TextAttributes {} struct FontSize: HeterogeneousDictionaryKey { typealias Domain = TextAttributes typealias Value = Double } struct Font: HeterogeneousDictionaryKey { typealias Domain = TextAttributes typealias Value = NSFont } struct ForegroundColor: HeterogeneousDictionaryKey { typealias Domain = TextAttributes typealias Value = NSColor } Yes, this is fairly long, which is one of the downsides of this approach. At least you only have to write it once per "keyspace". I'll walk you through it step by step. Notes on the API Using types as keys As you can see in this line, the dictionary keys are types (more precisely, metatype values): dict[FontSize.self] = 24 This is another parallel with the SwiftUI environment, which also uses types as keys (the p