title: Compile safety for UserDefaults publisher instead of crash?
body: <p>The <code>UserDefaults</code> publisher allows you subscribe even though the property is not compliant:</p>
  <pre><code>enum Direction: String {
      case north, south, east, west
  }
  
  extension UserDefaults {
      
      var direction: Direction {
          get { Direction(rawValue: string(forKey: &quot;direction&quot;) ?? &quot;&quot;) ?? .north }
          set { set(newValue.rawValue, forKey: &quot;direction&quot;) }
      }
  }
  
  let defaults = UserDefaults.standard
  var cancellable = Set&lt;AnyCancellable&gt;()
  
  defaults
      .publisher(for: \.direction)
      .sink { print(&quot;Sink: \($0)&quot;) } // Crash 
      .store(in: &amp;cancellable)
  
  defaults.direction = .east
  cancellable.removeAll()
  </code></pre>
  <p>The above code compiles and gives no warning either. At runtime, it crashes in the <code>sink</code>:</p>
  <pre><code>error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
  The process has been left at the point where it was interrupted, use &quot;thread return -x&quot; to return to the state before expression evaluation.
  
  Fatal error: Could not extract a String from KeyPath Swift.ReferenceWritableKeyPath&lt;__C.NSUserDefaults, __lldb_expr_43.Direction&gt;: file Foundation/NSObject.swift, line 124
  </code></pre>
  <p>I'll probably end up creating a private string version and expose it through a publisher like this:</p>
  <pre><code>extension UserDefaults {
      
      @objc private var directionRaw: String? {
          get { string(forKey: &quot;direction&quot;) }
          set { set(newValue, forKey: &quot;direction&quot;) }
      }
      
      var directionPublisher: AnyPublisher&lt;Direction, Never&gt; {
          publisher(for: \.directionRaw)
              .compactMap { [weak self] _ in self?.direction }
              .eraseToAnyPublisher()
      }
      
      var direction: Direction {
          get { Direction(rawValue: directionRaw ?? &quot;&quot;) ?? .north  }
          set { directionRaw = newValue.rawValue }
      }
  }
  
  defaults
      .directionPublisher
      .sink { print(&quot;Sink: \($0)&quot;) }
      .store(in: &amp;cancellable)
  </code></pre>
  <p>The problem is anyone can still do this in the codebase:</p>
  <pre><code>defaults
      .publisher(for: \.direction)
      .sink { print(&quot;Sink: \($0)&quot;) } // Crash 
      .store(in: &amp;cancellable)
  </code></pre>
  <p>Is there a way to prevent anyone from doing this, or hopefully there's a better way to do this altogether?</p>