code: function promisify(fn, opts) {
    switch (typeof fn) {
      case 'object':
        switch (typeof opts) {
          case 'string':
          case 'number':
            if (typeof fn[opts] !== 'function') {
              throw new TypeError('Function not found key: ' + opts);
            }
            if (fn[opts].__isPromisified__) {
              return fn[opts];
            }
            return makeFunctionByKey(fn, opts);
          default:
            throw new TypeError('Second argument is invalid');
        }
      case 'function':
        if (fn.__isPromisified__) {
          return fn;
        }
        const ctx = opts && opts.context !== undefined ? opts.context : undefined;
        return makeFunction(fn, ctx);
      default:
        throw new TypeError('Type of first argument is not function');
    }
  }
docs: @param {Object|Function} fn
  @param {string|number|Object} [fn]
  @param {Object} [fn.context]
  @example
  const func = (a, b, c, callback) => callback(null, a + b + c);
  Aigle.promisify(func)(1, 2, 3)
  .then(value => console.log(value)); // 6
  
  @example
  const obj = {
  val: 1,
  get(callback) {
  callback(null, this.val);
  }
  };
  
  // using bind
  Aigle.promisify(obj.get.bind(obj))().then(console.log);
  
  // using context
  Aigle.promisify(obj.get, { context: obj })().then(console.log);
  
  // using shorthand
  Aigle.promisify(obj, 'get')().then(console.log);