getTypeName = (type, src) => {
  if(!type) { return ''}
  if (type.typeName && type.typeName.escapedText) {
    const typeName = type.typeName.escapedText
    if(type.typeArguments && type.typeArguments.length) {
      const args = type.typeArguments.map(subType => getTypeName(subType, src)).join(', ')
      return `${typeName}<${args}>`
    } else {
      return typeName
    }
  }
  if(ts.isFunctionTypeNode(type) || ts.isFunctionLike(type)) {
    // it replaces ():void => {} (and other) to simple function
    return 'function'
  }
  if (ts.isArrayTypeNode(type)) {
    return 'Array'
  }
  if (type.types) {
    return type.types.map(subType => getTypeName(subType, src)).join(' | ')
  }
  if (type.members && type.members.length) {
    return 'object'
  }
  return src.substring(type.pos, type.end).trim()
}
Get type from a node
@param {ts.TypeNode} type which should be parsed to string
@param {string} src      source for an entire parsed file
@returns {string}    node type