TypeaheadTypeScriptCopy import { fromEvent, from } from 'rxjs'; import { map, filter, tap, mergeMap, reduce } from 'rxjs/operators'; let inputElement = document.querySelector('#typeahead-input') as HTMLElement; let containerElement = document.querySelector('#typeahead-container') as HTMLElement; let listOfProgrammingLanguages = [ 'python', 'javascript', 'java', 'c#', 'c++', 'ruby', 'go', 'swift', 'kotlin', 'php', 'typescript', 'scala', 'shell', 'perl', 'rust', 'r', 'dart', 'elixir', 'clojure', 'lua', 'haskell', 'julia', 'c', 'objective-c', 'groovy', 'assembly', 'coffeescript', 'fortran', 'matlab', 'pascal' ]; fromEvent(inputElement, 'keyup') .pipe( // Map each input event to the lowercase value of the input field. map((event): string => event.target.value.trim().toLowerCase()), // Clear the container element whenever the input changes. tap(() => containerElement.innerHTML = ''), filter(value => value.length > 2), // For each input value, map it to the filtered list of programming languages. mergeMap(value => from(listOfProgrammingLanguages) .pipe( // Filter the programming languages to only those that include the input value. filter(language => language.includes(value)), map(language => language.replace(value, `<strong>${value}</strong>`)), // Accumulate the filtered and highlighted programming languages into an array. reduce((accumulated: string[], language) => accumulated.concat(language), []) ) ) ) .subscribe( // For each accumulated array of filtered and highlighted programming languages, // update the container element's HTML to display the list. (filteredLanguages: string[]) => containerElement.innerHTML += `<div>${filteredLanguages.join('<div></div>')}</div>` );