title: Extend TypeScript / JavaScript native objects in a safe way with Sweet.JS hygienic macros (like extension methods)
body: <p>The <a href="https://www.sweetjs.org" rel="nofollow noreferrer">https://www.sweetjs.org</a> library allows to transform JavaScript code. I wonder if it would be possible to use it to extend native objects like Array, Object, String etc. in a safe way, without attaching anything to their prototype.</p>
  
  <p>It seems like sweet.js should be able to transform this JS code</p>
  
  <pre><code>{ a: 1 }.isEmpty()
  </code></pre>
  
  <p>Into</p>
  
  <pre><code>Extensions.isEmpty({ a: 1 })
  </code></pre>
  
  <p>And the implementation could be</p>
  
  <pre><code>Extensions.isEmpty = (o) =&gt; {
    if ('isEmpty' in o) return o.isEmpty()
    for (const k in o) if (o.hasOwnProperty(k)) return false
    return true
  }
  </code></pre>
  
  <p>But I'm not sure <strong>what code should I write in Sweet.JS to make that work</strong>?</p>
  
  <p>P.S. </p>
  
  <p>And with TypeScript it should work even better. We can trick TypeScript into thinking that our objects are extended by giving it false declaration below, and then after TypeScript compilation apply Sweet.JS compilation.</p>
  
  <pre><code>declare global {
    interface Object {
      isEmpty(): boolean
    }
  }
  </code></pre>
  
  <p>So we get all the correct typings for extensions, and our native objects would stay perfectly clean.</p>