import {Book, Librarian, Logger as DamageLogger} from './interfaces'; import {Category} from './enums'; import {Catalog, ReferenceItem, UniversityLibrarian} from './classes'; import { CalculateLateFees as CalcFee, MaxBooksAllowed, Purge } from './lib/utilityfunctions'; import refBook from './encyclopedia'; import {Books, LogAndReturn} from './generics'; export function GetAllBooks(): Book[] { const books = [ { author: 'James Joyce', available: true, category: Category.Fiction, id: 1, title: 'Ulysses', }, { author: 'Ernest Hemingway', available: false, category: Category.Fiction, id: 2, title: 'A farewall to arms', }, { author: 'Maya Angelou', available: true, category: Category.Poetry, id: 3, title: 'I know why the caged bird sings', }, { author: 'Herman Melville', available: true, category: Category.Fiction, id: 4, title: 'Moby Dick', } ]; return books; } export function LogFirstAvailable(books = GetAllBooks()): void { const numberOfBooks: number = books.length; let firstAvailable: string = ''; for (let currentBook of books) { if (currentBook.available) { firstAvailable = currentBook.title; break; } } console.log(`Total number of books: ${numberOfBooks}.`); console.log(`First available: ${firstAvailable}.`); } export function CheckoutBooks(customer: string, ...bookIds: number[]): string[] { console.log(`Checking out books for ${customer}.`); let booksCheckedOut: string[] = []; for (let id of bookIds) { let book = GetBookById(id); if (book.available) { booksCheckedOut.push(book.title); } } return booksCheckedOut; } export function CreateCustomer(name: string, age?: number, city?: string) { console.log(`Name: ${name}.`); if (age) { console.log(`Age: ${age}.`); } if (city) { console.log(`City: ${city}.`); } } export function CreateCustomerId(chars: string, nums: number): string { return chars + nums; } export function GetBookTitlesByCategory(categoryFilter: Category = Category.Fiction): Array { console.log(`Getting books in category: ${Category[categoryFilter]}.`); const allBooks = GetAllBooks(); const filteredTitles: string[] = []; for (let currentBook of allBooks) { if (currentBook.category === categoryFilter) { filteredTitles.push(currentBook.title); } } return filteredTitles; } export function GetBookById(id: number): Book { const allBooks = GetAllBooks(); return allBooks.filter(book => book.id === id)[0]; } export function LogBookTitles(titles: string[]): void { for (let title of titles) { console.log(title); } } // Note: no implementation. export function GetTitles(author: string): string[]; export function GetTitles(available: boolean): string[]; // Now an implementation: export function GetTitles(bookProperty: any): string[] { const allBooks = GetAllBooks(); const foundTitles: Array = []; if (typeof bookProperty == 'string') { // get books by author, add to foundTitles for (let book of allBooks) { if (book.author === bookProperty) { foundTitles.push(book.title); } } } else if (typeof bookProperty === 'boolean') { // get available books, add to foundTitles for (let book of allBooks) { if (book.available === bookProperty) { foundTitles.push(book.title); } } } else { throw new Error('Invalid property type: ' + typeof bookProperty); } return foundTitles; } export function PrintBook(book: Book): void { console.log(`${book.title} by ${book.author}.`); } //****************************************************************************** function bookDemo() { let myBook: Book = { author: 'Jane Austen', available: true, category: Category.Fiction, // copies: 3, id: 5, pages: 250, title: 'Pride and prejudice', // year: '1813', markDamaged: reason => console.log(`Damaged: ${reason}.`), }; PrintBook(myBook); myBook.markDamaged!('Torn back cover'); let logDamage: DamageLogger = reason => console.log(`Damage reported: ${reason}.`); logDamage('Coffee stains'); } function classDemo() { let favoriteLibrarian: Librarian = new UniversityLibrarian(); favoriteLibrarian.name = 'Sharon'; favoriteLibrarian.assistCustomer('Lynda'); // let ref: ReferenceItem = new ReferenceItem('Facts and Figures', 2016); // ref.publisher = 'Random Data publisher'; // ref.printItem(); // console.log(ref.publisher); let Newspaper = class extends ReferenceItem { printCitation(): void { console.log(`Newspaper: ${this.title}.`); } }; let myPaper = new Newspaper('The gazette', 2016); myPaper.printCitation(); class Novel extends class { title: string } { mainCharacter: string; } let favoriteNovel = new Novel(); favoriteNovel.mainCharacter = 'Hero'; favoriteNovel.title = 'Plot'; console.log(favoriteNovel); } function importDemo() { let fee = CalcFee(10); let max = MaxBooksAllowed(12); console.log(`Fee: ${fee}, max books: ${max}.`); let ref = new refBook('Fact Book', 2016, 1); console.log(ref); } function genericFunctionDemo() { LogAndReturn(false); LogAndReturn(42); LogAndReturn({ a: []}); interface Magazine { title: string } let someString: string = LogAndReturn('log this'); console.log('Returned: ', someString); let newMag: Magazine = { title: 'Web dev monthly' }; let someMag: Magazine = LogAndReturn(newMag); console.log('Returned mag', someMag); } function purgedemo() { let inventory: Books = [ { author: 'K & R', available: true, category: Category.Software, id: 10, title: 'The C programming language', }, { author: 'Steve McConnell', available: true, category: Category.Software, id: 11, title: 'Code Complete', }, { author: 'A. B.', available: true, category: Category.Software, id: 12, title: '8-Bit graphics with Cobol', }, { author: 'C. D.', available: true, category: Category.Software, id: 13, title: 'Cool autoexec.bat scripts', } ]; // Inventory is accepted because Books is an alias for Array, so the // signature actually matches. let purgedBooks: Books = Purge(inventory); // Note that purgedBooks uses the aliases type after the assignment. purgedBooks.forEach(book => console.log(book.title)); let purgedNums: Array = Purge([1, 2, 3, 4]); console.log(purgedNums); } function genericClassDemo() { let cat = new Catalog(); let books = GetAllBooks(); cat.addItem(books[0]); } false && bookDemo(); false && classDemo(); false && importDemo(); false && genericFunctionDemo(); false && purgedemo(); false && genericClassDemo();