├── Chapter05 ├── LLNode.txt ├── arraySum.txt ├── count.txt ├── getFeed.txt ├── binarySearch.txt ├── skipOdd.txt ├── createOrReplace.txt ├── traverse.txt ├── createOrReplace2.txt ├── MathOperations.txt ├── filterList.txt ├── reverse.txt ├── tests.txt └── LinkedList.txt ├── Chapter03 ├── declarationmerging │ ├── Questions │ │ ├── namespacewithdeclr.txt │ │ ├── multipleinterface.txt │ │ ├── namespacewithdeclr2.txt │ │ └── multiplenamepace.txt │ └── Answers │ │ ├── ans3.txt │ │ ├── ans4.txt │ │ ├── ans1.txt │ │ ├── ans2.txt │ │ └── ans5.txt ├── Mixin │ └── Tree.txt └── Arrowfunc │ └── Treenode.txt ├── Chapter08 ├── Gulp │ └── gulptask.txt └── MSBuild │ └── project.txt ├── Chapter04 ├── Event loop │ ├── feedFetchCompleted.txt │ ├── feedQuery.txt │ ├── loadHomeScreen_Sybchronous.txt │ ├── loadHomeScreen_Asynchronous.txt │ ├── getFeed_NeverReturns.txt │ ├── FetchMultipleFeeds.txt │ └── FeedCategory.txt ├── Synchronous fetch │ └── synchronous.txt ├── Asynchronous fetch │ └── asynchrnous.txt └── Asyncawait │ ├── PromiseFunction.txt │ └── asyncawait.txt ├── .gitattributes ├── Chapter02 ├── Namespaces │ ├── file2.ts │ ├── file3.ts │ └── file1.ts └── VariableDeclrtn │ └── vardeclr.txt ├── Chapter01 ├── Operators │ ├── logical.txt │ └── compoundassignment.txt ├── Classes and Interfaces │ ├── FeedRenderer.txt │ └── SNFG.txt ├── Strings │ ├── Concatenation.txt │ ├── Replacement.txt │ └── Literals.txt ├── Loop │ ├── forloop.txt │ └── forinloop.txt └── Array │ └── Sorting.txt ├── Chapter06 └── critical rendering path │ ├── Application1.txt │ └── index.html ├── .gitignore ├── Chapter07 ├── memoryprof.txt └── sortalgrthm.txt ├── LICENSE └── README.md /Chapter05/LLNode.txt: -------------------------------------------------------------------------------- 1 | // Linked List Node 2 | class LLNode { 3 | public data: number; 4 | public next: LLNode; 5 | 6 | constructor(data: number) { 7 | this.data = data; 8 | this.next = null; 9 | } 10 | } -------------------------------------------------------------------------------- /Chapter05/arraySum.txt: -------------------------------------------------------------------------------- 1 | public arraySum(arr: number[]): number { 2 | if (!arr || arr.length == 0) return 0; 3 | let result: number = 0; 4 | for (let i: number = 0; i < arr.length; i++) 5 | result += arr[i]; 6 | return result; 7 | } -------------------------------------------------------------------------------- /Chapter05/count.txt: -------------------------------------------------------------------------------- 1 | // returns the number of elements in the linked list 2 | public count(): number { 3 | let temp: LLNode = this.head; 4 | let count: number = 0; 5 | while(temp != null) { 6 | temp = temp.next; 7 | count++; 8 | } 9 | return count; 10 | } -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Questions/namespacewithdeclr.txt: -------------------------------------------------------------------------------- 1 | namespace TreeNode { 2 | export let node: TreeNode = TreeNode.AVLTreeNode; 3 | let id: number = 54; 4 | } 5 | 6 | enum TreeNode { 7 | RedBlackTreeNode, 8 | AVLTreeNode, 9 | TrieNode, 10 | SuffixTreeNode 11 | } -------------------------------------------------------------------------------- /Chapter05/getFeed.txt: -------------------------------------------------------------------------------- 1 | public getFeed(feedCategory: FeedCategory): IUserFeed[] { 2 | const resultFeed: IUserFeed[] = []; 3 | this.fakeUserFeed.forEach((userFeed: IUserFeed) => { 4 | if (userFeed.feedCategory === feedCategory) 5 | resultFeed.push(userFeed); 6 | }); 7 | return resultFeed; 8 | } -------------------------------------------------------------------------------- /Chapter08/Gulp/gulptask.txt: -------------------------------------------------------------------------------- 1 | var gulp = require("gulp"); 2 | gulp.task("default", function () { 3 | var ts = require("gulp-typescript"); 4 | var tsResult = gulp.src("src/*.ts") 5 | .pipe(ts({ 6 | noImplicitAny: true, 7 | out: "output.js" 8 | })); 9 | return tsResult.js.pipe(gulp.dest("built/local")); 10 | }); -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Answers/ans3.txt: -------------------------------------------------------------------------------- 1 | namespace TreeNode { 2 | export let node: TreeNode = TreeNode.AVLTreeNode; // refers 3 | to the enum 'TreeNode' 4 | let id: number = 54; 5 | } 6 | 7 | enum TreeNode { 8 | RedBlackTreeNode, 9 | AVLTreeNode, 10 | TrieNode, 11 | SuffixTreeNode 12 | } -------------------------------------------------------------------------------- /Chapter05/binarySearch.txt: -------------------------------------------------------------------------------- 1 | public binarySearch(arr: number[], key: number): number { 2 | if (key > arr[4]) { 3 | if (key > arr[7]) { 4 | if (key > arr[8]) { 5 | if (key == arr[9]) { 6 | return 9; 7 | } 8 | } 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /Chapter05/skipOdd.txt: -------------------------------------------------------------------------------- 1 | public skipOdd(): void { 2 | if (!this.head) { 3 | return; 4 | } 5 | 6 | let temp: LLNode = this.head.next; 7 | this.head = temp; 8 | 9 | while (temp != null && temp.next != null) { 10 | temp.next = temp.next.next; 11 | temp = temp.next; 12 | } 13 | } -------------------------------------------------------------------------------- /Chapter05/createOrReplace.txt: -------------------------------------------------------------------------------- 1 | // create or replace the linked list starting at 'head' 2 | public createOrReplace(input: number[]): void { 3 | this.head = new LLNode(input[0]); 4 | let temp: LLNode = this.head; 5 | 6 | for(let i: number = 1; i < input.length; i++) { 7 | temp.next = new LLNode(input[i]); 8 | temp = temp.next; 9 | } 10 | } -------------------------------------------------------------------------------- /Chapter05/traverse.txt: -------------------------------------------------------------------------------- 1 | // returns a string representation of all the elements in the 2 | linked list starting from head 3 | public traverse(): string { 4 | let temp: LLNode = this.head; 5 | let result: string = ''; 6 | while(temp != null) { 7 | result+=temp.data + ','; 8 | temp = temp.next; 9 | } 10 | return result; 11 | } -------------------------------------------------------------------------------- /Chapter04/Event loop/feedFetchCompleted.txt: -------------------------------------------------------------------------------- 1 | const feedFetchCompleted: ICallback = (result: IUserFeed[], 2 | err: Error): void => { 3 | console.log('Callback called!', Date.now()-baseStartTime); 4 | if (err) { 5 | console.log('Error fetching feed: ', err); 6 | } else { 7 | console.log('Succesfully fetched feed of length: ', 8 | result.length); 9 | } 10 | } -------------------------------------------------------------------------------- /Chapter04/Event loop/feedQuery.txt: -------------------------------------------------------------------------------- 1 | const feedQuery: FeedQuery = new FeedQuery(); 2 | const baseStartTime: number = Date.now(); 3 | console.log('Fetching Text Feed - ', Date.now() - 4 | baseStartTime); 5 | feedQuery.getFeed(FeedCategory.Text, feedFetchCompleted); 6 | console.log('Fetching Audio Feed', Date.now() - 7 | baseStartTime); 8 | feedQuery.getFeed(FeedCategory.Audio, feedFetchCompleted); -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /Chapter02/Namespaces/file2.ts: -------------------------------------------------------------------------------- 1 | namespace TSCafe { 2 | export class BreakRoomCafe extends Cafe implements ICafe { 3 | makeSelection(selection: CoffeeSelections): void { 4 | if (selection === CoffeeSelections.Macchiato) { 5 | console.log('Sorry, this selection is not available at 6 | Break Room!'); 7 | } else { 8 | super.makeSelection(selection); 9 | } 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter05/createOrReplace2.txt: -------------------------------------------------------------------------------- 1 | public createOrReplace(input: number[]): void { 2 | if (!input || input.length == 0) { 3 | this.head = null; 4 | return; 5 | } 6 | 7 | this.head = new LLNode(input[0]); 8 | let temp: LLNode = this.head; 9 | 10 | for(let i: number = 1; i < input.length; i++) { 11 | temp.next = new LLNode(input[i]); 12 | temp = temp.next; 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter05/MathOperations.txt: -------------------------------------------------------------------------------- 1 | class MathOperations { 2 | public square(x: number): number { 3 | return x * x; 4 | } 5 | 6 | public add(x: number, y: number): number { 7 | return x + y; 8 | } 9 | 10 | public square(x: string): number { 11 | let num: number = Number(x); 12 | if (!x) { 13 | return -1; 14 | } 15 | return num * num; 16 | } 17 | } -------------------------------------------------------------------------------- /Chapter01/Operators/logical.txt: -------------------------------------------------------------------------------- 1 | const condition: boolean = x > 0 && x < 10; // simple 2 | condition AND 3 | 4 | this.instanceVariable && this.instanceVariable.DoOperation(); 5 | /* AND used to check for non-null instance variable, and then 6 | perform the operation on that instance. */ 7 | 8 | // This could also be written as 9 | 10 | if (this.instanceVariable) { 11 | this.instanceVariable.DoOperation(); 12 | } -------------------------------------------------------------------------------- /Chapter05/filterList.txt: -------------------------------------------------------------------------------- 1 | public filterList(maxValue: number): LinkedList { 2 | let temp: LLNode = this.head; 3 | const arr: number[] = []; 4 | 5 | while(temp != null) { 6 | if (temp.data > maxValue) break; // return 7 | arr.push(temp.data); 8 | temp = temp.next; 9 | } 10 | const resultList: LinkedList = new LinkedList(); 11 | resultList.createOrReplace(arr); 12 | return resultList; 13 | } -------------------------------------------------------------------------------- /Chapter02/Namespaces/file3.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | const receptionCafe: TSCafe.ReceptionCafe = new 5 | TSCafe.ReceptionCafe(); 6 | receptionCafe.pay(TSCafe.PaymentOptions.Credit); 7 | 8 | const breakRoomCafe: TSCafe.BreakRoomCafe = new 9 | TSCafe.BreakRoomCafe(); 10 | breakRoomCafe.pay(TSCafe.PaymentOptions.Debit); 11 | breakRoomCafe.makeSelection(TSCafe.CoffeeSelections.Macchiato); 12 | breakRoomCafe.makeSelection(TSCafe.CoffeeSelections.Pune); 13 | breakRoomCafe.dispense(); -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Answers/ans4.txt: -------------------------------------------------------------------------------- 1 | class TreeNode { 2 | private root: TreeNode = TreeNode.node; 3 | // private id: number = TreeNode.id; // error: 'id' not 4 | exported and thus cannot be accessed here 5 | private data: number; 6 | 7 | constructor(data: number) { 8 | this.data = data; 9 | } 10 | } 11 | 12 | // re-ordered namespace to follow after the class declaration 13 | namespace TreeNode { 14 | export let node: TreeNode = new TreeNode(10); 15 | let id: number = 54; 16 | } -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Answers/ans1.txt: -------------------------------------------------------------------------------- 1 | interface TreeNode { 2 | data: number; 3 | left: TreeNode; 4 | right: TreeNode; 5 | createNode: (data: number) => TreeNode; 6 | } 7 | 8 | interface ITreeOperations {// root: TreeNode; 9 | // error: same name member declarations 10 | cannot merge 11 | mirrorTree: (node: TreeNode) => TreeNode; 12 | putRoot(nodeValue: number): void; 13 | getRoot(): TreeNode; 14 | traverseTree: (node: TreeNode) => void; 15 | putRoot(node: TreeNode): void; 16 | getRoot(): TreeNode; 17 | } -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Questions/multipleinterface.txt: -------------------------------------------------------------------------------- 1 | interface TreeNode { 2 | data: number; 3 | left: TreeNode; 4 | right: TreeNode; 5 | createNode: (data: number) => TreeNode; 6 | } 7 | 8 | interface ITreeOperations { 9 | root: TreeNode; 10 | traverseTree: (node: TreeNode) => void; 11 | putRoot(node: TreeNode): void; 12 | getRoot(): TreeNode; 13 | } 14 | 15 | interface ITreeOperations { 16 | root: TreeNode; 17 | mirrorTree: (node: TreeNode) => TreeNode; 18 | putRoot(nodeValue: number): void; 19 | getRoot(): TreeNode; 20 | } -------------------------------------------------------------------------------- /Chapter05/reverse.txt: -------------------------------------------------------------------------------- 1 | // reverse the linked list and returns the head of the 2 | reversed list 3 | public reverse(): LLNode { 4 | let prev: LLNode = null; 5 | let curr: LLNode = this.head; 6 | let next: LLNode; 7 | 8 | // start traversing from the head 9 | while (curr != null) 10 | { 11 | next = curr.next; 12 | curr.next = prev; // flip the next pointer of the current 13 | node 14 | prev = curr; // current node will become the next node's 15 | previous 16 | curr = next; // move to the next node 17 | } 18 | return prev; 19 | } -------------------------------------------------------------------------------- /Chapter04/Synchronous fetch/synchronous.txt: -------------------------------------------------------------------------------- 1 | const loadHomeScreen_Synchronous = (startTime: number) => { 2 | // fetch public feed synchronously, takes around ~10s 3 | for (let i = 0; i < 5000000000; i++) {} 4 | console.log('Fetched Profile Info - ', Date.now() - startTime); 5 | console.log('Fetched Friends Feed - ', Date.now() - startTime); 6 | console.log('Fetched and Loaded Notifications - ', Date.now() - 7 | startTime); 8 | console.log('Fetched and Loaded Friend Suggestions - ', 9 | Date.now() - startTime); 10 | console.log('Fetched Public Feed - ', Date.now() - startTime); 11 | } 12 | 13 | // Synchronous Data Fetch 14 | loadHomeScreen_Synchronous(Date.now()); -------------------------------------------------------------------------------- /Chapter04/Event loop/loadHomeScreen_Sybchronous.txt: -------------------------------------------------------------------------------- 1 | const loadHomeScreen_Synchronous = (startTime: number) => { 2 | // fetch public feed synchronously, takes around ~10s 3 | for (let i = 0; i < 5000000000; i++) {} 4 | console.log('Fetched Public Feed - ', Date.now() - 5 | startTime); 6 | console.log('Fetched Profile Info - ', Date.now() - 7 | startTime); 8 | console.log('Fetched Friends Feed - ', Date.now() - 9 | startTime); 10 | console.log('Fetched and Loaded Notifications - ', 11 | Date.now() - startTime); 12 | console.log('Fetched and Loaded Friend Suggestions - ', 13 | Date.now() - startTime); 14 | } -------------------------------------------------------------------------------- /Chapter04/Asynchronous fetch/asynchrnous.txt: -------------------------------------------------------------------------------- 1 | const loadHomeScreen_Asynchronous = (startTime: number) => { 2 | // fetch public feed asynchronously, takes around ~10s 3 | setTimeout(() => { 4 | console.log('Fetched Public Feed - ', Date.now() - startTime); 5 | }, 10000); 6 | console.log('Fetched Profile Info - ', Date.now() - startTime); 7 | console.log('Fetched Friends Feed - ', Date.now() - startTime); 8 | console.log('Fetched and Loaded Notifications - ', Date.now() - 9 | startTime); 10 | console.log('Fetched and Loaded Friend Suggestions - ', 11 | Date.now() - startTime); 12 | } 13 | 14 | // Asynchronous Data Fetch 15 | loadHomeScreen_Asynchronous(Date.now()); -------------------------------------------------------------------------------- /Chapter04/Event loop/loadHomeScreen_Asynchronous.txt: -------------------------------------------------------------------------------- 1 | const loadHomeScreen_Asynchronous = (startTime: number) => { 2 | // fetch public feed asynchronously, takes around ~10s 3 | setTimeout(() => { 4 | console.log('Fetched Public Feed - ', Date.now() - 5 | startTime); 6 | }, 10000); 7 | console.log('Fetched Profile Info - ', Date.now() - 8 | startTime); 9 | console.log('Fetched Friends Feed - ', Date.now() - 10 | startTime); 11 | console.log('Fetched and Loaded Notifications - ', 12 | Date.now() - startTime); 13 | console.log('Fetched and Loaded Friend Suggestions - ', 14 | Date.now() - startTime); 15 | } -------------------------------------------------------------------------------- /Chapter04/Asyncawait/PromiseFunction.txt: -------------------------------------------------------------------------------- 1 | function PromiseFunction(): Promise { 2 | return new Promise((resolve, reject) => { 3 | setTimeout(() => { 4 | resolve("Hello World"); 5 | }, 5000); 6 | }); 7 | } 8 | 9 | // Function prefixed with the "async" keyword 10 | async function AsyncFunction() { 11 | const result: string = await PromiseFunction(); 12 | console.log('Asynchronous work completes - ', Date.now() - 13 | baseStartTime); 14 | console.log('Result: ', result); 15 | } 16 | 17 | console.log('Asynchronous work starts - ', Date.now() - 18 | baseStartTime); 19 | AsyncFunction(); 20 | console.log('Other work continues - ', Date.now() - 21 | baseStartTime); -------------------------------------------------------------------------------- /Chapter04/Event loop/getFeed_NeverReturns.txt: -------------------------------------------------------------------------------- 1 | public getFeed_NeverReturns(feedCategory: FeedCategory, callback: 2 | ICallback): void { 3 | console.log(FeedCategory[feedCategory] + ' fetch begins', 4 | Date.now() - baseStartTime); 5 | 6 | // simulating an asynchronous network request 7 | setTimeout(() => { 8 | let resultFeed: IUserFeed[] = []; 9 | this.fakeUserFeed.forEach((userFeed: IUserFeed) => { 10 | if (userFeed.feedCategory === feedCategory) { 11 | resultFeed.push(userFeed); 12 | } 13 | }); 14 | console.log('resultFeed is available to be returned but callback 15 | never called!'); 16 | }, 5000); 17 | } 18 | 19 | feedQuery.getFeed_NeverReturns(FeedCategory.Text, 20 | feedFetchCompleted); -------------------------------------------------------------------------------- /Chapter06/critical rendering path/Application1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | Social Network X 13 | 14 | 15 | {{feed[0].content}} 16 | {{feed[0].commentsAndLikes}} 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Answers/ans2.txt: -------------------------------------------------------------------------------- 1 | namespace HeightBalancedTree { 2 | export interface BalanceFactor { 3 | calculateLevelDifference(node1: AVLTreeNode, node2: 4 | AVLTreeNode): number; 5 | } 6 | 7 | export interface AVLTreeNode { 8 | data: number; 9 | height: number; // color: Color; 10 | // error: this member was not exported and 11 | hence isn't visible to the merged namespace 12 | left: AVLTreeNode; 13 | right: AVLTreeNode; 14 | } 15 | 16 | export function getRootNodeColor(): Color { // return 17 | rootNodeColor; // error: this member was not 18 | exported and hence isn't visible to the merged namespace 19 | } 20 | } -------------------------------------------------------------------------------- /Chapter01/Operators/compoundassignment.txt: -------------------------------------------------------------------------------- 1 | // 1. compound assignments 2 | let num: number = 40; 3 | num *= 2; // num1 equals 80. this is same as num = num * 2 4 | 5 | // 2. typeof 6 | const str: String = 'test'; 7 | console.log(typeof num); // outputs number 8 | console.log(typeof str === 'string'); // outputs true 9 | 10 | // 3. instanceof 11 | const arr: number[] = [1,2,3]; 12 | class ABC {}; 13 | const abc: ABC = new ABC(); 14 | 15 | console.log(arr instanceof Object); // outputs true 16 | console.log(arr instanceof Array); // outputs true 17 | console.log(abc instanceof Object); // outputs true 18 | console.log(abc instanceof ABC); // outputs true 19 | console.log(arr instanceof ABC); // outputs false -------------------------------------------------------------------------------- /Chapter01/Classes and Interfaces/FeedRenderer.txt: -------------------------------------------------------------------------------- 1 | class FeedRenderer { 2 | private recentFeedGenerator: Feeder.IFeedGenerator; 3 | private popularFeedGenerator: Feeder.IFeedGenerator; 4 | 5 | constructor(universalKey: string) { 6 | this.recentFeedGenerator = Feeder.FeedGeneratorFactory 7 | (Feeder.FeedStrategy.Recent, universalKey); 8 | this.popularFeedGenerator = Feeder.FeedGeneratorFactory 9 | (Feeder.FeedStrategy.Popular, universalKey); 10 | } 11 | 12 | public getRecentFeed(): Feeder.IFeed[] { 13 | return this.recentFeedGenerator && this.recentFeedGenerator 14 | .getFeed(); 15 | } 16 | 17 | public getPopularFeed(): Feeder.IFeed[] { 18 | return this.popularFeedGenerator && 19 | this.popularFeedGenerator.getFeed(10); 20 | } 21 | } -------------------------------------------------------------------------------- /Chapter06/critical rendering path/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 19 | 20 | 21 | Social Network X 22 | 23 | 24 | {{feed[0].content}} 25 | {{feed[0].commentsAndLikes}} 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /Chapter02/VariableDeclrtn/vardeclr.txt: -------------------------------------------------------------------------------- 1 | // var tests 2 | function varTest1(): () => number { 3 | x = 16; 4 | return function innerFunction(): number { 5 | x++; 6 | y--; 7 | if (x > 100) { 8 | var y; 9 | } 10 | return x; 11 | } 12 | var x; 13 | x = 'hello-world'; 14 | } 15 | 16 | function varTest2(): () => number { 17 | x = 16; 18 | return function innerFunction(): number { 19 | var x; 20 | return x; 21 | } 22 | var x; 23 | x = 'hello-world'; 24 | } 25 | 26 | function varTest3(): () => number { 27 | x = 16; 28 | return function innerFunction(): number { 29 | x++; 30 | var x; 31 | return x; 32 | } 33 | var x; 34 | x = 'hello-world'; 35 | } 36 | 37 | console.log('var test 1: ', varTest1()()); 38 | console.log('var test 2: ', varTest2()()); 39 | console.log('var test 3: ', varTest3()()); -------------------------------------------------------------------------------- /Chapter04/Asyncawait/asyncawait.txt: -------------------------------------------------------------------------------- 1 | const baseStartTime: number = Date.now(); 2 | 3 | const feedQuery: FeedQuery = new FeedQuery(); 4 | 5 | // Fetch Text, Image, and AudioVideo Feed 6 | async function FetchMultipleFeeds() { 7 | const textFeed: IUserFeed[] = await feedQuery 8 | .getFeed(FeedCategory.Text); 9 | const imageFeed: IUserFeed[] = await feedQuery 10 | .getFeed(FeedCategory.Image); 11 | const audioVideoFeed: IUserFeed[] = await feedQuery 12 | .getFeed(FeedCategory.AudioVideo); 13 | console.log('Successfully fetched Text, Image, and AudioVideo 14 | Feed - ', Date.now() - baseStartTime); 15 | console.log('Total Feed Length: ', textFeed.length + 16 | imageFeed.length + audioVideoFeed.length); 17 | } 18 | 19 | console.log('Fetch Text, Image, and AudioVideo Feed - ', 20 | Date.now() - baseStartTime); 21 | 22 | FetchMultipleFeeds(); 23 | 24 | console.log('Do other work - ', Date.now() - baseStartTime); -------------------------------------------------------------------------------- /Chapter07/memoryprof.txt: -------------------------------------------------------------------------------- 1 | function createString(): string { 2 | return 'Lorem Ipsum is simply dummy text of the printing and 3 | typesetting industry. Lorem Ipsum has been the industry''s 4 | standard dummy text ever since the 1500s, when an unknown 5 | printer took a galley of type and scrambled it to make 6 | a type specimen book. It has survived not only five centuries, 7 | but also the leap into electronic typesetting, remaining 8 | essentially unchanged. It was popularised in the 1960s with 9 | the release of Letraset sheets containing Lorem Ipsum passages, 10 | and more recently with desktop publishing software like Aldus 11 | PageMaker including versions of Lorem Ipsum.'; 12 | } 13 | let time1: number = Date.now(); 14 | let s1: string = ''; 15 | for (let i = 0; i < 40000; i++) { 16 | s1 = s1.concat(createString()); 17 | } 18 | let time2: number = Date.now(); 19 | console.log('Time difference: ', time 2 - time1); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter04/Event loop/FetchMultipleFeeds.txt: -------------------------------------------------------------------------------- 1 | async function FetchMultipleFeeds(): Promise { 2 | const textFeed: IUserFeed[] = await feedQuery. 3 | getFeed(FeedCategory.Text); 4 | const imageFeed: IUserFeed[] = await feedQuery. 5 | getFeed(FeedCategory.Image); 6 | const audioFeed: IUserFeed[] = await feedQuery. 7 | getFeed(FeedCategory.Audio); 8 | const audioVideoFeed: IUserFeed[] = await feedQuery. 9 | getFeed(FeedCategory.AudioVideo); 10 | console.log('Succesfully fetched Text, Image, and AudioVideo 11 | Feed - ', Date.now() - baseStartTime); 12 | console.log('Total Feed Length: ', textFeed.length + 13 | imageFeed.length + audioVideoFeed.length); 14 | } 15 | 16 | console.log('Fetch Text, Image, and AudioVideo Feed - ', 17 | Date.now() 18 | - baseStartTime); 19 | 20 | FetchMultipleFeeds() 21 | .catch((reject: Error) => { 22 | console.log('Error during FetchMultipleFeeds - ', Date.now() - 23 | baseStartTime); 24 | console.log('Error: ', reject); 25 | }); 26 | 27 | console.log('Do other work - ', Date.now() - baseStartTime); -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Answers/ans5.txt: -------------------------------------------------------------------------------- 1 | function TreeSum(): number { 2 | return TreeSum_R(TreeSum.root); 3 | } 4 | 5 | function TreeSum_R(node: TreeNode): number { 6 | return node === null ? 0 : node.value + TreeSum_R(node.left) 7 | + TreeSum_R(node.right); 8 | } 9 | 10 | class Tree { 11 | private root: TreeNode; 12 | 13 | constructor() { 14 | this.root = new TreeNode(10); 15 | this.root.left = new TreeNode(5); 16 | this.root.right = new TreeNode(15); 17 | } 18 | 19 | public getRoot(): TreeNode { 20 | return this.root; 21 | } 22 | } 23 | 24 | class TreeNode { 25 | public value: number; 26 | public left: TreeNode; 27 | public right: TreeNode; 28 | 29 | constructor(val: number) { 30 | this.value = val; 31 | this.left = this.right = null; 32 | } 33 | } 34 | 35 | namespace TreeSum { 36 | let tree: Tree = new Tree(); 37 | export let root: TreeNode = tree.getRoot(); 38 | } 39 | 40 | console.log('Sum is: ', TreeSum()); -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Questions/namespacewithdeclr2.txt: -------------------------------------------------------------------------------- 1 | function TreeSum(): number { 2 | return TreeSum_R(TreeSum.root); 3 | } 4 | 5 | function TreeSum_R(node: TreeNode): number { 6 | return node === null ? 0 : node.value + TreeSum_R(node.left) 7 | + TreeSum_R(node.right); 8 | } 9 | 10 | class Tree { 11 | private root: TreeNode; 12 | 13 | constructor() { 14 | this.root = new TreeNode(10); 15 | this.root.left = new TreeNode(5); 16 | this.root.right = new TreeNode(15); 17 | } 18 | 19 | public getRoot(): TreeNode { 20 | return this.root; 21 | } 22 | } 23 | 24 | class TreeNode { 25 | public value: number; 26 | public left: TreeNode; 27 | public right: TreeNode; 28 | 29 | constructor(val: number) { 30 | this.value = val; 31 | this.left = this.right = null; 32 | } 33 | } 34 | 35 | namespace TreeSum { 36 | let tree: Tree = new Tree(); 37 | export let root: TreeNode = tree.getRoot(); 38 | } 39 | 40 | console.log('Sum is: ', TreeSum()); -------------------------------------------------------------------------------- /Chapter01/Strings/Concatenation.txt: -------------------------------------------------------------------------------- 1 | function createString(): string { 2 | return `Lorem Ipsum is simply dummy text of the printing and 3 | typesetting industry. Lorem Ipsum has been the industry''s 4 | standard dummy text ever since the 1500s, when an unknown 5 | printer took a galley of type and scrambled it to make a type 6 | specimen book. It has survived not only five centuries, but also 7 | the leap into electronic typesetting, remaining essentially 8 | unchanged. It was popularised in the 1960s with the release of 9 | Letraset sheets containing Lorem Ipsum passages, and more 10 | recently with desktop publishing software like Aldus PageMaker 11 | including versions of Lorem Ipsum.`; 12 | } 13 | 14 | let time1: number = Date.now(); 15 | let s1: string = ''; 16 | 17 | for (let i = 0; i < 40000; i++) { 18 | s1 = s1.concat(createString()); 19 | } 20 | 21 | let time2: number = Date.now(); 22 | console.log('Time difference: ', time2 - time1); 23 | 24 | let s2: string = ''; 25 | time1 = Date.now(); 26 | 27 | for (let i = 0; i < 400000; i++) { 28 | s2 += createString(); 29 | } 30 | 31 | time2 = Date.now(); 32 | console.log('Time difference: ', time2 - time1); -------------------------------------------------------------------------------- /Chapter07/sortalgrthm.txt: -------------------------------------------------------------------------------- 1 | const arr: number[] = []; 2 | let temp: number = 0; 3 | const randomizeArray = () => { 4 | for (let i = 0; i < 45000; i++) { 5 | arr[i] = Math.floor(Math.random() * 100000); 6 | } 7 | } 8 | // naive 9 | const naiveSort = () => { 10 | for (let i = 0; i < arr.length; i++) { 11 | for (let j = 0; j < arr.length - 1; j++) { 12 | if (arr[j] > arr[j + 1]) { 13 | temp = arr[j]; 14 | arr[j] = arr[j + 1]; 15 | arr[j + 1] = temp; 16 | } 17 | } 18 | } 19 | } 20 | // optimized 21 | const optimizedSort = () => { 22 | let swapped: boolean = true; 23 | while (swapped) { 24 | for (let j = 0; j < arr.length - 1; j++) { 25 | swapped = false; 26 | if (arr[j] > arr[j + 1]) { 27 | swapped = true; 28 | temp = arr[j]; 29 | arr[j] = arr[j + 1]; 30 | arr[j + 1] = temp; 31 | } 32 | } 33 | } 34 | } 35 | const calculateTimeDifference = (func: () => void): number => { 36 | randomizeArray(); 37 | const time1: number = Date.now(); 38 | func(); 39 | const time2: number = Date.now(); 40 | return time2 - time1; 41 | } -------------------------------------------------------------------------------- /Chapter03/declarationmerging/Questions/multiplenamepace.txt: -------------------------------------------------------------------------------- 1 | namespace HeightBalancedTree { 2 | enum Color {Red, Black}; 3 | let rootNodecolor = Color.Red; 4 | 5 | export interface BalanceFactor { 6 | calculateLevelDifference(node1: RedBlackTreeNode, node2: 7 | RedBlackTreeNode): number; 8 | } 9 | 10 | export interface RedBlackTreeNode { 11 | data: number; 12 | color: Color; 13 | left: RedBlackTreeNode; 14 | right: RedBlackTreeNode; 15 | } 16 | 17 | export interface Node extends RedBlackTreeNode {} 18 | 19 | export function getNodeData(node: Node): any { 20 | return {data: node.data, color: node.color}; 21 | } 22 | } 23 | 24 | namespace HeightBalancedTree { 25 | export interface BalanceFactor { 26 | calculateLevelDifference(node1: AVLTreeNode, node2: 27 | AVLTreeNode): number; 28 | } 29 | 30 | export interface AVLTreeNode { 31 | data: number; 32 | height: number; 33 | color: Color; 34 | left: AVLTreeNode; 35 | right: AVLTreeNode; 36 | } 37 | 38 | export function getRootNodeColor(): Color { 39 | return rootNodeColor; 40 | } 41 | } -------------------------------------------------------------------------------- /Chapter01/Strings/Replacement.txt: -------------------------------------------------------------------------------- 1 | function createString(): string { 2 | return `Lorem Ipsum is simply dummy text of the printing and 3 | typesetting industry. Lorem Ipsum has been the industry''s 4 | standard dummy text ever since the 1500s, when an unknown 5 | printer took a galley of type and scrambled it to make a type 6 | specimen book. It has survived not only five centuries, but 7 | also the leap into electronic typesetting, remaining 8 | essentially unchanged. It was popularised in the 1960s with the 9 | release of Letraset sheets containing Lorem Ipsum passages, and 10 | more recently with desktop publishing software like Aldus 11 | PageMaker including versions of Lorem Ipsum.`; 12 | } 13 | let baseString: string = createString(); 14 | const replacementCharacter: string = '|'; 15 | let time1: number = Date.now(); 16 | for (let i = 0; i < 50000; i++) { 17 | baseString.split(' ').join(replacementCharacter); 18 | } 19 | let time2: number = Date.now(); 20 | console.log('Time difference (SplitJoin): ', time2 - time1); 21 | time1 = Date.now(); 22 | for (let i = 0; i < 50000; i++) { 23 | baseString.replace(/ /g , replacementCharacter); 24 | } 25 | time2 = Date.now(); 26 | console.log('Time difference (Replace_w_RegExp): ', time2 - 27 | time1); -------------------------------------------------------------------------------- /Chapter01/Loop/forloop.txt: -------------------------------------------------------------------------------- 1 | const arr: Array = []; 2 | let temp: number = 0; 3 | 4 | const randomizeArray = () => { 5 | for (let i = 0; i < 50000; i++) { 6 | arr[i] = Math.floor(Math.random() * 100000); 7 | } 8 | } 9 | 10 | // dummy method 11 | const dummy = () => null; 12 | 13 | // for...in 14 | const forinLoop = () => { 15 | let dummy: number; 16 | for (let i in arr) { 17 | dummy = arr[i]; 18 | } 19 | } 20 | 21 | // for...of 22 | const forofLoop = () => { 23 | let dummy: number; 24 | for (let i of arr) { 25 | dummy = i; 26 | } 27 | } 28 | 29 | // naive 30 | const naiveLoop = () => { 31 | let dummy: number; 32 | for (let i = 0; i < arr.length; i++) { 33 | dummy = arr[i]; 34 | } 35 | } 36 | 37 | const calculateTimeDifference = (func: () => void): number => { 38 | randomizeArray(); 39 | const time1: number = Date.now(); 40 | func(); 41 | const time2: number = Date.now(); 42 | return time2 - time1; 43 | } 44 | 45 | console.log('Time Difference (forof): ', calculateTimeDifference 46 | (forofLoop)); 47 | console.log('Time Difference (forin): ', calculateTimeDifference 48 | (forinLoop)); 49 | console.log('Time Difference (naive): ', calculateTimeDifference 50 | (naiveLoop)); -------------------------------------------------------------------------------- /Chapter01/Array/Sorting.txt: -------------------------------------------------------------------------------- 1 | const arr: number[] = []; 2 | let temp: number = 0; 3 | 4 | const randomizeArray = () => { 5 | for (let i = 0; i < 50000; i++) { 6 | arr[i] = Math.floor(Math.random() * 100000); 7 | } 8 | } 9 | 10 | // naive 11 | const naiveSort = () => { 12 | for (let i = 0; i < arr.length; i++) { 13 | for (let j = 0; j < arr.length - 1; j++) { 14 | if (arr[j] > arr[j + 1]) { 15 | temp = arr[j]; 16 | arr[j] = arr[j + 1]; 17 | arr[j + 1] = temp; 18 | } 19 | } 20 | } 21 | } 22 | 23 | // optimized 24 | const optimizedSort = () => { 25 | let swapped: boolean = true; 26 | while (swapped) { 27 | for (let j = 0; j < arr.length - 1; j++) { 28 | swapped = false; 29 | if (arr[j] > arr[j + 1]) { 30 | swapped = true; 31 | temp = arr[j]; 32 | arr[j] = arr[j + 1]; 33 | arr[j + 1] = temp; 34 | } 35 | } 36 | } 37 | } 38 | 39 | const calculateTimeDifference = (func: () => void): number => { 40 | randomizeArray(); 41 | const time1: number = Date.now(); 42 | func(); 43 | const time2: number = Date.now(); 44 | return time2 - time1; 45 | } -------------------------------------------------------------------------------- /Chapter03/Mixin/Tree.txt: -------------------------------------------------------------------------------- 1 | class Tree { 2 | public root: TreeNode = null; 3 | 4 | // construct the input BST we covered earlier 5 | public constructTree(): void { 6 | this.root = new TreeNode(4); 7 | this.root.left = new TreeNode(2); 8 | this.root.right = new TreeNode(5); 9 | this.root.left.left = new TreeNode(1); 10 | this.root.left.right = new TreeNode(3); 11 | this.root.right.left = new TreeNode(6); 12 | this.root.right.right = new TreeNode(7); 13 | } 14 | } 15 | 16 | // Traversable Mixin - Mixin #2 17 | class Traversable { 18 | // inorder traversal starting at 'node' 19 | public traverse(node: TreeNode) { 20 | const inorder_R = (node: TreeNode): void => { 21 | if (node == null) return; 22 | inorder_R(node.left); 23 | console.log(node.data); 24 | inorder_R(node.right); 25 | } 26 | inorder_R(node); 27 | } 28 | } 29 | 30 | // Mirrorble Mixin - Mixin #3 31 | class Mirrorable { 32 | public mirror(node: TreeNode): TreeNode { 33 | const mirror_R = (node: TreeNode): TreeNode => { 34 | if (node == null) return null; 35 | mirror_R(node.left); 36 | mirror_R(node.right); 37 | // swap the left and right subtrees 38 | let temp: TreeNode = node.left; 39 | node.left = node.right; 40 | node.right = temp; 41 | return node; 42 | } 43 | return mirror_R(node); 44 | } 45 | } -------------------------------------------------------------------------------- /Chapter08/MSBuild/project.txt: -------------------------------------------------------------------------------- 1 | 2 | xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 | 4 | 6 | 7 | 12 | 13 | 14 | false 15 | true 16 | 17 | 18 | true 19 | false 20 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /Chapter01/Loop/forinloop.txt: -------------------------------------------------------------------------------- 1 | const calculateTimeDifference = (func: () => void): number => { 2 | const time1: number = Date.now(); 3 | func(); 4 | const time2: number = Date.now(); 5 | return time2 - time1; 6 | } 7 | 8 | const generateGuid = (): string => { 9 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, 10 | (c: string) => { 11 | const r = Math.random() * 16 | 0, 12 | v = c == 'x' ? r : (r & 0x3 | 0x8); 13 | return v.toString(16); 14 | }); 15 | } 16 | 17 | interface Map { 18 | [key: string]: string; 19 | } 20 | 21 | const map: Map = {}; 22 | 23 | for (let i = 0; i < 50000; i++) { 24 | map[(i+1).toString()] = generateGuid(); 25 | } 26 | 27 | // for...in 28 | const mapForIn = () => { 29 | let dummy: string; 30 | for (let key in map) { 31 | dummy = key; 32 | } 33 | } 34 | 35 | // for...of 36 | const mapForOf = () => { 37 | let dummy: string; 38 | const keys = Object.keys(map); 39 | for (let key of keys) { 40 | dummy = key; 41 | } 42 | } 43 | 44 | // naive 45 | const mapForNaive = () => { 46 | let dummy: string; 47 | const keys = Object.keys(map); 48 | for (let i = 0; i < 50000; i++) { 49 | dummy = keys[i]; 50 | } 51 | } 52 | 53 | console.log('Time Difference (map:forof): ', 54 | calculateTimeDifference(mapForOf)); 55 | console.log('Time Difference (map:forin): ', 56 | calculateTimeDifference(mapForIn)); 57 | console.log('Time Difference (map:naive): ', 58 | calculateTimeDifference(mapForNaive)); -------------------------------------------------------------------------------- /Chapter01/Classes and Interfaces/SNFG.txt: -------------------------------------------------------------------------------- 1 | export enum FeedStrategy { Recent, Popular, MediaOnly }; 2 | 3 | 4 | enum SocialMediaPlatform { Facebook, Instagaram, Snapchat, 5 | Twitter, StackOverflow }; 6 | 7 | export interface IFeed { 8 | platformId: SocialMediaPlatform; 9 | content: string; 10 | media: string 11 | } 12 | 13 | 14 | export interface IFeedGenerator { 15 | getFeed(limit?: number): IFeed[]; 16 | } 17 | 18 | 19 | class RecentFeedGenerator implements IFeedGenerator { 20 | private authenticate(universalKey: string): void { 21 | 22 | } 23 | 24 | public getFeed(limit?: number): IFeed[] { 25 | 26 | { 27 | custom algorithm to optimally calculate most recent social 28 | media feed for the user, across all the available social 29 | media platforms 30 | } 31 | } 32 | } 33 | 34 | 35 | class PopularFeedGenerator implements IFeedGenerator { 36 | private authenticate(universalKey: string): void { 37 | 38 | } 39 | 40 | public getFeed(limit?: number): IFeed[] { 41 | 42 | return []; 43 | } 44 | } 45 | 46 | 47 | 48 | 49 | export function FeedGeneratorFactory(feedStrategy: FeedStrategy, 50 | universalKey: string): IFeedGenerator { 51 | let feedGenerator: IFeedGenerator = null; 52 | switch (feedStrategy) { 53 | case FeedStrategy.Recent: { 54 | feedGenerator = new RecentFeedGenerator(); 55 | break; 56 | } 57 | case FeedStrategy.Popular: { 58 | feedGenerator = new RecentFeedGenerator(); 59 | break; 60 | } 61 | } 62 | return feedGenerator; 63 | } -------------------------------------------------------------------------------- /Chapter03/Arrowfunc/Treenode.txt: -------------------------------------------------------------------------------- 1 | class TreeNode { 2 | public data: number; 3 | public left: TreeNode; 4 | public right: TreeNode; 5 | 6 | constructor(data: number) { 7 | this.data = data; 8 | this.left = this.right = null; 9 | } 10 | 11 | public printData1(): void { 12 | console.log(this.data); 13 | console.log('this (TreeNode): ', this); 14 | } 15 | 16 | public printData2 = (): void => { 17 | console.log(this.data); 18 | console.log('this (TreeNode): ', this); 19 | } 20 | } 21 | 22 | // class Tree 23 | class Tree { 24 | private root: TreeNode; 25 | 26 | constructor() { 27 | this.root = null; 28 | } 29 | 30 | public constructTree(): void { 31 | this.root = new TreeNode(10); 32 | this.root.left = new TreeNode(5); 33 | this.root.right = new TreeNode(15); 34 | } 35 | 36 | public treeTraverser1(): () => void { 37 | const traverseTree_R = function (node: TreeNode): void { 38 | if (node == null) return; 39 | console.log(node.data); 40 | traverseTree_R(node.left); 41 | traverseTree_R(node.right); 42 | } 43 | return function () { 44 | traverseTree_R(this.root); 45 | } 46 | } 47 | 48 | public treeTraverser2(): () => void { 49 | const traverseTree_R = (node: TreeNode): void => { 50 | if (node == null) return; 51 | console.log(node.data); 52 | traverseTree_R(node.left); 53 | traverseTree_R(node.right); 54 | } 55 | return () => { 56 | traverseTree_R(this.root); 57 | } 58 | } 59 | 60 | public printRoot(nodePrinter: () => void): void { 61 | console.log(this.root.data); 62 | console.log('this (Tree): ', this); 63 | nodePrinter(); 64 | } 65 | } -------------------------------------------------------------------------------- /Chapter01/Strings/Literals.txt: -------------------------------------------------------------------------------- 1 | function createString_1(): string { 2 | return `Lorem Ipsum is simply dummy text of the printing and 3 | typesetting industry. Lorem Ipsum has been the industry''s 4 | standard dummy text ever since the 1500s, when an unknown 5 | printer took a galley of type and scrambled it to make a type 6 | specimen book. It has survived not only five centuries, but also 7 | the leap into electronic typesetting, remaining essentially 8 | unchanged.It was popularised in the 1960s with the release of 9 | Letraset sheets containing Lorem Ipsum passages, and more 10 | recently with desktop publishing software like Aldus PageMaker 11 | including versions of Lorem Ipsum.`; 12 | } 13 | 14 | function createString_2(): String { 15 | return new String(`Lorem Ipsum is simply dummy text of the 16 | printing and typesetting industry. Lorem Ipsum has been the 17 | industry''s standard dummy text ever since the 1500s, when an 18 | unknown printer took a galley of type and scrambled it to make a 19 | type specimen book. It has survived not only five centuries, but 20 | also the leap into electronic typesetting, remaining essentially 21 | unchanged. It was popularised in the 1960s with the release of 22 | Letraset sheets containing Lorem Ipsum passages, and more 23 | recently with desktop publishing software like Aldus PageMaker 24 | including versions of Lorem Ipsum.`); 25 | } 26 | 27 | // calculate time taken to create 50, 000 'strings' 28 | let time1: number = Date.now(); 29 | for (let i = 0; i < 50000; i++) { 30 | createString_1(); 31 | } 32 | 33 | let time2: number = Date.now(); 34 | console.log('Time difference (createString_1): ', time2 - time1); 35 | 36 | // calculate time taken to create 50, 000 'Strings' 37 | time1 = Date.now(); 38 | for (let i = 0; i < 50000; i++) { 39 | createString_2(); 40 | } 41 | 42 | time2 = Date.now(); 43 | console.log('Time difference (createString_2): ', time2 - time1); -------------------------------------------------------------------------------- /Chapter05/tests.txt: -------------------------------------------------------------------------------- 1 | // test.ts - Unit testing the LinkedList class 2 | import * as LinkedList from './src'; 3 | import { expect, assert } from 'chai'; 4 | import 'mocha'; 5 | 6 | describe('Linked List Manipulations', () => { 7 | 8 | const linkedList: LinkedList.LinkedList = new 9 | LinkedList.LinkedList(); 10 | // tests createOrReplace method 11 | it('should create a 5 element linked list', () => { 12 | linkedList.createOrReplace([1,2,3,4,5]); 13 | expect(linkedList.traverse()).to.equal('1,2,3,4,5,'); 14 | expect(linkedList.getHead().data).to.equal(1); 15 | expect(linkedList.count()).to.be.at.least(3); 16 | }); 17 | 18 | // tests createOrReplace method 19 | it('should not create a linked list, head stays null', () => { 20 | linkedList.createOrReplace([]); 21 | expect(linkedList.getHead()).to.equal(null); 22 | expect(linkedList.count()).to.equal(0); 23 | expect(linkedList.traverse()).to.have.lengthOf(0); 24 | }); 25 | 26 | // tests reverse method 27 | it('should reverse the linked list and return the tail as the 28 | head', () => { 29 | linkedList.createOrReplace([1,2,3]); 30 | assert.strictEqual(linkedList.reverse().data, 3); 31 | assert.isAbove(linkedList.count(), 0); 32 | }); 33 | 34 | // tests filterList method 35 | it('should filter the 7 element linked list to return a list with 36 | values < 100', () => { 37 | linkedList.createOrReplace([45, 87, 105, 12, 45, 167, 144]); 38 | const newList: LinkedList.LinkedList = linkedList. 39 | filterList(100); 40 | expect(newList.count()).to.equal(4); 41 | }); 42 | 43 | // tests skipOdd method 44 | it('should skip odd position elements and return 2->4->6', () => 45 | { 46 | linkedList.createOrReplace([1, 2, 3, 4, 5, 6]); 47 | linkedList.skipOdd(); 48 | expect(linkedList.traverse()).to.equal('2,4,6,'); 49 | expect(linkedList.getHead()).to.not.equal(null); 50 | }); 51 | 52 | // tests skipOdd method 53 | it('should skip odd position elements in an empty list', () => { 54 | linkedList.createOrReplace([]); 55 | linkedList.skipOdd(); 56 | expect(linkedList.traverse()).to.equal(''); 57 | expect(linkedList.getHead()).to.equal(null); 58 | }); 59 | }); -------------------------------------------------------------------------------- /Chapter02/Namespaces/file1.ts: -------------------------------------------------------------------------------- 1 | namespace TSCafe { 2 | 3 | export enum CoffeeSelections { Latte, Espresso, Mocha, Pune, 4 | Macchiato, Cappuccino }; 5 | export enum PaymentOptions { Credit, Debit, Gift, Cash }; 6 | 7 | export interface ICafe { 8 | pay(paymentOption: PaymentOptions): void; 9 | makeSelection(selection: CoffeeSelections): void; 10 | dispense(): void; 11 | } 12 | 13 | export class Cafe implements ICafe { 14 | // simplified representation of payment validation 15 | paymentValidated(paymentOption: PaymentOptions): boolean { 16 | // validate payment type and return validation results 17 | return true; 18 | } 19 | 20 | // simplified representation of selection availability check 21 | selectionAvailable(selection: CoffeeSelections): boolean { 22 | // validate payment type and return validation results 23 | return true; 24 | } 25 | 26 | pay(paymentOption: PaymentOptions) { 27 | if (this.paymentValidated(paymentOption)) { 28 | console.log('Payment Successful! Select your beverage.'); 29 | } else { 30 | console.log('Payment failed! Try again or try a different 31 | payment option.'); 32 | } 33 | } 34 | 35 | makeSelection(selection: CoffeeSelections): void { 36 | if (this.selectionAvailable(selection)) { 37 | console.log('Selection Confirmed!'); 38 | } else { 39 | console.log('Sorry, we are out of ', selection, '. Please 40 | select a different beverage!'); 41 | } 42 | } 43 | 44 | dispense(): void { 45 | console.log('Dispensing...'); 46 | } 47 | } 48 | 49 | export class ReceptionCafe extends Cafe implements ICafe { 50 | pay(paymentOption: PaymentOptions) { 51 | if (paymentOption !== PaymentOptions.Cash) { 52 | console.log('Sorry, only cash payments accepted at 53 | Reception!'); 54 | } else { 55 | super.pay(paymentOption); 56 | } 57 | } 58 | 59 | makeSelection(selection: CoffeeSelections): void { 60 | if (selection === CoffeeSelections.Pune) { 61 | console.log('Sorry, this selection is not available at 62 | Reception!'); 63 | } else { 64 | super.makeSelection(selection); 65 | } 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Chapter05/LinkedList.txt: -------------------------------------------------------------------------------- 1 | export class LinkedList { 2 | private head: LLNode; 3 | 4 | constructor() { 5 | this.head = null; 6 | } 7 | 8 | // create or replace the linked list starting at 'head' 9 | public createOrReplace(input: number[]): void { 10 | this.head = new LLNode(input[0]); 11 | let temp: LLNode = this.head; 12 | 13 | for(let i: number = 1; i < input.length; i++) { 14 | temp.next = new LLNode(input[i]); 15 | temp = temp.next; 16 | } 17 | } 18 | 19 | // returns the number of elements in the linked list 20 | public count(): number { 21 | let temp: LLNode = this.head; 22 | let count: number = 0; 23 | while(temp != null) { 24 | temp = temp.next; 25 | count++; 26 | } 27 | return count; 28 | } 29 | 30 | // returns a string representation of all the elements in the 31 | linked list starting from head 32 | public traverse(): string { 33 | let temp: LLNode = this.head; 34 | let result: string = ''; 35 | while(temp != null) { 36 | result+=temp.data + ','; 37 | temp = temp.next; 38 | } 39 | return result; 40 | } 41 | 42 | // returns the head node 43 | public getHead(): LLNode { 44 | return this.head; 45 | } 46 | 47 | // reverse the linked list and returns the head of the reversed 48 | list 49 | public reverse(): LLNode { 50 | let prev: LLNode = null; 51 | let curr: LLNode = this.head; 52 | let next: LLNode; 53 | 54 | // start traversing from the head 55 | while (curr != null) 56 | { 57 | next = curr.next; 58 | curr.next = prev; // flip the next pointer of the current node 59 | prev = curr; // current node will become the next node's 60 | previous 61 | curr = next; // move to the next node 62 | } 63 | return prev; 64 | } 65 | 66 | // returns a new list with values less than maxValue 67 | public filterList(maxValue: number): LinkedList { 68 | let temp: LLNode = this.head; 69 | const arr: number[] = []; 70 | 71 | while(temp != null) { 72 | if (temp.data > maxValue) break; // return 73 | arr.push(temp.data); 74 | temp = temp.next; 75 | } 76 | const resultList: LinkedList = new LinkedList(); 77 | resultList.createOrReplace(arr); 78 | return resultList; 79 | } 80 | 81 | // skips the elements at odd positions 82 | public skipOdd(): void { 83 | let temp: LLNode = this.head.next; 84 | this.head = temp; 85 | 86 | while (temp != null && temp.next != null) { 87 | temp.next = temp.next.next; 88 | temp = temp.next; 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /Chapter04/Event loop/FeedCategory.txt: -------------------------------------------------------------------------------- 1 | enum FeedCategory { Text, Image, Audio, AudioVideo }; 2 | 3 | interface IUserFeed { 4 | feedId: number; 5 | feedCategory: FeedCategory; 6 | content: string; 7 | time: number; 8 | } 9 | 10 | interface ICallback { 11 | (result: IUserFeed[], err: Error): void; 12 | } 13 | 14 | class FeedQuery { 15 | 16 | // private variables 17 | private fakeUserFeed: IUserFeed[] = [{ 18 | feedId: 156, 19 | feedCategory: FeedCategory.Text, 20 | content: "Hello World", 21 | time: 1201 22 | }, { 23 | feedId: 76, 24 | feedCategory: FeedCategory.Text, 25 | content: "On top of Mount Rainer!", 26 | time: 1156 27 | }, { 28 | feedId: 12, 29 | feedCategory: FeedCategory.Image, 30 | content: "http://fakeUrl.com/test.jpeg", 31 | time: 1789 32 | }, { 33 | feedId: 79, 34 | feedCategory: FeedCategory.AudioVideo, 35 | content: "http://fakeUrl.com/test1.mov", 36 | time: 1555 37 | }, { 38 | feedId: 5, 39 | feedCategory: FeedCategory.AudioVideo, 40 | content: "http://fakeUrl.com/test2.mov", 41 | time: 1452 42 | }, { 43 | feedId: 109, 44 | feedCategory: FeedCategory.Text, 45 | content: "Best Lunch ever!", 46 | time: 1109 47 | }]; 48 | 49 | // public methods 50 | public getFeed(feedCategory: FeedCategory, callback: ICallback): 51 | void { 52 | console.log(FeedCategory[feedCategory] + ' fetch begins', 53 | Date.now() - baseStartTime); 54 | 55 | // simulating an asynchronous network request 56 | setTimeout(() => { 57 | let resultFeed: IUserFeed[] = []; 58 | this.fakeUserFeed.forEach((userFeed: IUserFeed) => { 59 | if (userFeed.feedCategory === feedCategory) { 60 | resultFeed.push(userFeed); 61 | } 62 | }); 63 | if (resultFeed.length === 0) { 64 | callback(null, new Error("No feed found for the " + 65 | FeedCategory[feedCategory] + " category")); 66 | } else { 67 | callback(resultFeed, null); 68 | } 69 | }, 5000); 70 | } 71 | } 72 | 73 | const feedQuery: FeedQuery = new FeedQuery(); 74 | const feedFetchCompleted: ICallback = (result: IUserFeed[], err: 75 | Error): void => { 76 | console.log('Callback called!', Date.now() - baseStartTime); 77 | if (err) { 78 | console.log('Error fetching feed: ', err); 79 | } else { 80 | console.log('Succesfully fetched feed of length: ', 81 | result.length); 82 | } 83 | } 84 | 85 | const baseStartTime: number = Date.now(); 86 | 87 | console.log('Fetching Text Feed - ', Date.now() - 88 | baseStartTime); 89 | feedQuery.getFeed(FeedCategory.Text, feedFetchCompleted); 90 | 91 | console.log('Fetching Audio Feed', Date.now() - baseStartTime); 92 | feedQuery.getFeed(FeedCategory.Audio, feedFetchCompleted); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypeScript High Performance 2 | This is the code repository for [TypeScript High Performance](https://www.packtpub.com/application-development/typescript-high-performance?utm_source=github&utm_medium=repository&utm_campaign=9781785288647), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the book from start to finish. 3 | ## About the Book 4 | In a world where a tiny decrease in frames per second impacts customer engagement greatly, writing highly scalable code is more of a necessity than a luxury. Using TypeScript you get type checking during development. This gives you the power to write optimized code quickly. This book is also a solid tool to those who’re curious to understand the impact of performance in production, and it is of the greatest aid to the proactive developers who like to be cognizant of and avoid the classic pitfalls while coding. 5 | 6 | 7 | ## Instructions and Navigation 8 | All of the code is organized into folders. Each folder starts with a number followed by the application name. For example, Chapter02. 9 | 10 | 11 | 12 | The code will look like the following: 13 | ``` 14 | export enum FeedStrategy { Recent, Popular, MediaOnly }; 15 | 16 | export interface IFeed { ... }; 17 | 18 | export interface IFeedGenerator { ... }; 19 | 20 | export function FeedGeneratorFactory(feedStrategy: FeedStrategy, 21 | universalKey: string): IFeedGenerator { ... } 22 | ``` 23 | 24 | The book requires the following things: 25 | 26 | Node and NPM 27 | TypeScript 28 | Mocha Test Framework 29 | Chai Assertion Library 30 | Windows, Linux, or MacOS 31 | Modern browsers--Chrome, Edge, and IE 32 | Telerik Fiddler 33 | Frontend editor--preferably VS Code or Atom/Sublime Text 34 | 35 | ## References 36 | Chapter 1: 37 | * https://www.tutorialspoint.com/typescript/typescript_operators.htm 38 | 39 | Chapter 2: 40 | * https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html 41 | * https://www.typescriptlang.org/docs/handbook/variable-declarations.html 42 | 43 | Chapter 3: 44 | * https://www.typescriptlang.org/docs/handbook/functions.html 45 | * https://www.typescriptlang.org/docs/handbook/mixins.html 46 | * https://www.typescriptlang.org/docs/handbook/declaration-merging.html 47 | * https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html 48 | 49 | Chapter 4: 50 | * https://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/ 51 | * https://www.youtube.com/watch?v=8aGhZQkoFbQ 52 | 53 | Chapter 5: 54 | * https://journal.artfuldev.com/write-tests-for-typescript-projects-with-mocha-and-chai-in-typescript-86e053bdb2b6 55 | * https://github.com/palantir/tslint 56 | 57 | Chapter 6: 58 | * https://developers.google.com/web/fundamentals/performance/critical-rendering-path/ 59 | * https://en.wikipedia.org/wiki/Content_delivery_network 60 | * https://www.youtube.com/watch?v=YV1nKLWoARQ 61 | 62 | Chapter 7: 63 | * https://developers.google.com/web/tools/chrome-devtools/rendering-tools/ 64 | * http://www.telerik.com/fiddler/web-app-performance-testing 65 | * https://en.wikipedia.org/wiki/List_of_HTTP_status_codes 66 | 67 | Chapter 8: 68 | * https://www.typescriptlang.org/docs/handbook/integrating-with-build-tools.html 69 | 70 | ## Related Products 71 | * [Building Pro Web Apps with TypeScript 2.x [Video]](https://www.packtpub.com/application-development/building-pro-web-apps-typescript-2x-video?utm_source=github&utm_medium=repository&utm_campaign=9781788292054) 72 | 73 | * [Rapid Web Application Development with TypeScript 2.x [Video]](https://www.packtpub.com/application-development/rapid-web-application-development-typescript-2x-video?utm_source=github&utm_medium=repository&utm_campaign=9781787287389) 74 | 75 | * [Angular 2 Web Development with TypeScript [Video]](https://www.packtpub.com/web-development/angular-2-web-development-typescript-video?utm_source=github&utm_medium=repository&utm_campaign=9781785885563) 76 | --------------------------------------------------------------------------------
{{feed[0].content}}
{{feed[0].commentsAndLikes}}