TypeScript Tutorial
TypeScript Project: Library Catalog
A catalog of books with title, author, and year. Search by author and list every match.
What you will build
A catalog is an array of books. Each book has a title, an author, and a year. You print the full shelf, then search by author and list every match. Search uses includes so a last name can match inside a longer author field.
The shelf is hardcoded. Compile with Try it in TypeScript at/typescript/try. This is TypeScript, not a Python script and not a C++ file.
A Book interface
Three fields travel together. Title and author are strings. Year is a number. Printing one book is a single function so the catalog loop stays short.
Example
interface Book {
title: string;
author: string;
year: number;
}
function printBook(b: Book): void {
console.log(b.title + " - " + b.author + " (" + b.year + ")");
}
const b: Book = {
title: "Programming TypeScript",
author: "Boris Cherny",
year: 2019,
};
printBook(b);Fill a catalog
Book[] grows with push. A for...of loop prints every row. Pass the catalog into the print helper.
Example
interface Book {
title: string;
author: string;
year: number;
}
function printBook(b: Book): void {
console.log(b.title + " - " + b.author + " (" + b.year + ")");
}
function printCatalog(shelf: Book[]): void {
console.log("Catalog (" + shelf.length + " books)");
for (const b of shelf) {
printBook(b);
}
}
const shelf: Book[] = [];
shelf.push({ title: "Programming TypeScript", author: "Boris Cherny", year: 2019 });
shelf.push({ title: "Effective TypeScript", author: "Dan Vanderkam", year: 2019 });
shelf.push({ title: "TypeScript Cookbook", author: "Stefan Baumgartner", year: 2023 });
printCatalog(shelf);Run the catalog at /typescript/try via Try it in TypeScript. Two titles will share an author in the complete program. That pair is what the search in the next sections must return.
Search with includes
author.includes(query) is true when the query is a substring. A query of Chernymatches Boris Cherny. An empty query matching every book is possible with includes; this project treats an empty query as no hits so a blank search does not dump the shelf.
Example
const author: string = "Boris Cherny";
const query: string = "Cherny";
if (author.includes(query)) {
console.log("match");
} else {
console.log("no match");
}Complete catalog program
Walk the array. When the author field contains the query, print that book and count it. After the loop, print how many matches you found. Two searches run at the bottom of the file: one that hits twice, one that hits none.
Example
interface Book {
title: string;
author: string;
year: number;
}
function printBook(b: Book): void {
console.log(b.title + " - " + b.author + " (" + b.year + ")");
}
function searchByAuthor(shelf: Book[], query: string): void {
console.log("Search author: " + query);
if (query.length === 0) {
console.log("Empty query, 0 matches");
return;
}
let hits = 0;
for (const b of shelf) {
if (b.author.includes(query)) {
printBook(b);
hits = hits + 1;
}
}
console.log(hits + " match(es)");
}
const shelf: Book[] = [];
shelf.push({ title: "Programming TypeScript", author: "Boris Cherny", year: 2019 });
shelf.push({ title: "Effective TypeScript", author: "Dan Vanderkam", year: 2019 });
shelf.push({ title: "Learning TypeScript", author: "Josh Goldberg", year: 2022 });
shelf.push({ title: "TypeScript in 50 Lessons", author: "Stefan Baumgartner", year: 2020 });
shelf.push({ title: "TypeScript Cookbook", author: "Stefan Baumgartner", year: 2023 });
console.log("All books");
for (const b of shelf) {
printBook(b);
}
console.log("");
searchByAuthor(shelf, "Baumgartner");
console.log("");
searchByAuthor(shelf, "Ada");The Baumgartner search prints two titles and 2 match(es). The Ada search prints0 match(es). Search is case-sensitive: baumgartner would miss these rows.
Common mistakes
- Comparing authors with
===only. ThenBaumgartnerfails againstStefan Baumgartner. Useincludeswhen you want a substring. - Using
indexOfand testing against0. A match at the start of the string is index 0, which is a hit. The miss value is-1, or skip the index and useincludes. - Forgetting to count hits. Printing books without a total makes an empty result look like a crashed loop.
- Storing year as a string. Numeric year lets you add a filter such as “after 2020” later without parsing.
Practice
- Change the Ada search query to
Goldbergand confirm one match prints. - Add a sixth book by Dan Vanderkam and confirm that author search now lists two titles.
- Add a search-by-title function that also uses
includes, and print only books withyear >= 2022.
Next project: convert Celsius, Fahrenheit, and Kelvin with formatted output.