npm package: @kingjs/reflect.export-extension
Description: Extend a type with a property and return a symbol whose debug name is derived from the module hosting the extension.
Author: Chris King
Latest version: 1.0.3

# @[kingjs][@kingjs]/[reflect][ns0].[export-extension][ns1]
Extend a type with a property and return a symbol whose debug name is derived from the module hosting the extension.
## Usage
```js
var assert = require('assert');
var exportExtension = require('@kingjs/reflect.export-extension');
var IIterable = require('@kingjs/i-iterable');

// Assume the package is `@kingjs/ex` with version `1.0.0`.
var name = 'Symbol(@kingjs/ex, 1.0.0)';

/**
 * Export an extension `Rename` on Function that renames the
 * Function.  
 */
var Rename = exportExtension(
  module,
  Function,
  function(name) {
    Object.defineProperty(
      this, 'name', { value: name }
    )
  }
)
assert(module.exports == Rename);
assert(Rename.toString() == name);
//assert(Function.prototype[Rename].name == name);

function foo() { }
foo[Rename]('bar');
assert(foo.name == 'bar');

/**
 * Export an extension `Rename` on Function that renames the
 * Function, but this time as an accessor. Looks weird but 
 * illustrates using an accessor.
 */
var Rename = exportExtension(
  module,
  Function, {
    set: function(name) {
      Object.defineProperty(
        this, 'name', { value: name }
      )
    }
  }
)
function foo() { }
foo[Rename] = 'bar';
assert(foo.name == 'bar');

/**
 * Export an extension on Any() IIterable which is an Interface
 * implemented by all types with a Symbol.iterator property.
 */
var Any = exportExtension(
  module,
  IIterable,
  function() {
    var iterator = this[Symbol.iterator]();
    iterator = iterator.next();
    return !iterator.done;
  }
)

// string implements IIterable
assert(''[Any]() == false)
assert('foo'[Any]() == true)

// array implements IIterable
assert([][Any]() == false)
assert([ 0 ][Any]() == true)

/**
 * If the `kingjs` shim has been run, then String and Array
 * also implement IEnumerable which allows for extending
 * IEnumerable to implement `None` like this:
 */
var IEnumerable = require('@kingjs/i-enumerable');
var IEnumerator = require('@kingjs/i-enumerator');
var None = exportExtension(
  module,
  IEnumerable,
  function() {
    var enumerator = this[IEnumerable.getEnumerator]();
    return !enumerator[IEnumerator.moveNext]();
  }
)

require('kingjs');
require('@kingjs/assert-shimmed');

// string implements IEnumerable when shimmed
assert(''[None]() == true)
assert('foo'[None]() == false)

// array implements IEnumerable when shimmed
assert([][None]() == true)
assert([ 0 ][None]() == false)

```

## API
```ts
exportExtension(module, type, descriptor)
```

### Parameters
- `module`: The module hosting the extension.
- `type`: The type being extended.
- `descriptor`: The descriptor describing the property.
### Returns
Returns the symbol name of the property. The symbol is not registered. The symbol's debug name is the hosting module  name and its version.
### Remarks
If the type is an interface than all types implementing the  interface are extended.
Overloads are similar to those provided by  `@kingjs/reflect.define-property`

## Install
With [npm](https://npmjs.org/) installed, run
```
$ npm install @kingjs/reflect.export-extension
```
## Dependencies
|Package|Version|
|---|---|
|[`@kingjs/i-interface`](https://www.npmjs.com/package/@kingjs/i-interface)|`^1.0.3`|
|[`@kingjs/reflect.define-property`](https://www.npmjs.com/package/@kingjs/reflect.define-property)|`^1.0.0`|
## Source
https://repository.kingjs.net/reflect/export-extension
## License
MIT

![Analytics](https://analytics.kingjs.net/reflect/export-extension)

[@kingjs]: https://www.npmjs.com/package/kingjs
[ns0]: https://www.npmjs.com/package/@kingjs/reflect
[ns1]: https://www.npmjs.com/package/@kingjs/reflect.export-extension