Given a type description object, return legible string description
@param {Object} type
@return {String}
function inferType(type) {
  if (!type) return '';

  function iterateTypes(subTree) {
    return map(normalizeValue(subTree), inferType).join(', ');
  }

  switch (type.name) {
    case 'arrayOf':
      return `array of ${iterateTypes(type.value)}`;
    case 'custom':
      return COMMON_PROP_TYPES_TO_LINKS_MAP[type.raw] || type.raw;
    case 'enum':
      return `one of: ${iterateTypes(type.value)}`;
    case 'shape':
    case 'shapeOf': // FALL THROUGH
      return 'object';
    case 'union':
      return iterateTypes(type.value);
    default:
      return type.name || type.value;
  }
}