Symfony 3.x form types demo from DevmachineFormBundle. You can access Symfony 2.x demo here.

->add('language', TypeaheadType::class, [
    'label'       => 'Programming language',
    'source_name' => 'languages',
    'min_length'  => 1,
    'placeholder' => 'Start typing',
    'matcher'     => 'starts_with', // ends_with, contains
    'source'      => [
        'PHP', 'Ruby', 'Python', 'Go', 'Java', 'C', 'C++',
        'Javascript', 'ML', 'Racket', 'Lisp', 'Pascal',
    ],
])
->add('country', TypeaheadCountryType::class)
->add('timezone', TypeaheadTimezoneType::class)
->add('airport', TypeaheadType::class, [
    'source_name' => 'airports',
    'min_length'  => 2,
    'highlight'   => false, // Do not highlight current text
    'hint'        => false, // Do not show completion suggestion
    'label_key'   => 'city',
    'value_key'   => 'code',
    'source' => [
        ['code' => 'RIX', 'city' => 'Riga', 'country' => 'LV'],
        ['code' => 'LGW', 'city' => 'Gatwick', 'country' => 'UK'],
        ['code' => 'STN', 'city' => 'Stansted', 'country' => 'UK'],
        ['code' => 'LHR', 'city' => 'Heathrow', 'country' => 'UK'],
    ],
])
->add('language', TypeaheadLanguageType::class)
Custom form type
<?php

namespace AppBundle\Form\Type;

use Devmachine\Bundle\FormBundle\Form\Type\TypeaheadType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Intl\Intl;
use Symfony\Component\OptionsResolver\OptionsResolver;

class TypeaheadLanguageType extends AbstractType
{
    public function getParent()
    {
        return TypeaheadType::class;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'source_name' => 'languages',
            'route_name'  => 'typeahead_search',
            'min_length'  => 2,
            'limit'       => 10,
            'label_key'   => 'val',
            'value_key'   => 'key',
            'required'    => false,
        ]);
    }

    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $data = Intl::getLanguageBundle()->getLanguageNames();

        /*
         * When data is set, fetch the value from data source.
         *
         * For Doctrine:
         *  - inject a repository,
         *  - find entity by value e.g. id,
         *  - use appropriate property as display value.
         */
        if ($view->vars['value'] && isset($data[$view->vars['value']])) {
            $view->vars['typeahead_value'] = $data[$view->vars['value']];
        }
    }
}
Custom search action
/**
 * @Route("/search", name="typeahead_search", methods="get", condition="request.isXmlHttpRequest()")
 */
public function searchAction(Request $request)
{
    $query = strtolower($request->query->get('query'));

    $data = [];
    if (strlen($query) < 2) {
        return JsonResponse::create($data);
    }

    // Do the search, could be a database call.
    // Ensure keys are set according to form type.
    foreach (Intl::getLanguageBundle()->getLanguageNames() as $key => $val) {
        if (strpos(strtolower($val), $query) === 0) {
            $data[] = ['key' => $key, 'val' => $val];
        }
    }

    return JsonResponse::create($data);
}