├── A01 ├── .vs │ ├── Appendix01 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Appendix01.csproj ├── Appendix01.csproj.user ├── Appendix01.sln ├── Listing-A1-001.js ├── Listing-A1-002.js ├── Listing-A1-003.js ├── Listing-A1-004.js ├── Listing-A1-005.js ├── Listing-A1-006.js ├── Listing-A1-007.js ├── Listing-A1-008.js ├── Listing-A1-009.js ├── Listing-A1-010.js ├── Listing-A1-011.js ├── Listing-A1-012.js ├── Listing-A1-013.js └── obj │ └── Debug │ ├── Appendix01.csproj.CoreCompileInputs.cache │ └── DesignTimeResolveAssemblyReferencesInput.cache ├── A02 ├── app.ts └── module.ts ├── A03 ├── .vs │ ├── Appendix03 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Appendix03.csproj ├── Appendix03.csproj.user ├── Appendix03.sln ├── Listing-A3-001.js ├── Listing-A3-001.ts ├── Listing-A3-002.js ├── Listing-A3-002.ts └── obj │ └── Debug │ ├── Appendix03.csproj.CoreCompileInputs.cache │ └── DesignTimeResolveAssemblyReferencesInput.cache ├── CH01 ├── .vs │ ├── Chapter01 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter01.csproj ├── Chapter01.csproj.user ├── Chapter01.sln ├── Figure-1-001.ts ├── Figure-1-002.ts ├── Listing-1-001.js ├── Listing-1-002.js ├── Listing-1-002.ts ├── Listing-1-003.ts ├── Listing-1-004.js ├── Listing-1-004.ts ├── Listing-1-005.js ├── Listing-1-005.ts ├── Listing-1-006.ts ├── Listing-1-007.ts ├── Listing-1-008.js ├── Listing-1-008.ts ├── Listing-1-009.js ├── Listing-1-009.ts ├── Listing-1-010.js ├── Listing-1-010.ts ├── Listing-1-011.js ├── Listing-1-011.ts ├── Listing-1-012.js ├── Listing-1-012.ts ├── Listing-1-013.js ├── Listing-1-013.ts ├── Listing-1-014.js ├── Listing-1-015.ts ├── Listing-1-016.ts ├── Listing-1-017.ts ├── Listing-1-018.ts ├── Listing-1-019.js ├── Listing-1-019.ts ├── Listing-1-020.js ├── Listing-1-020.ts ├── Listing-1-021.ts ├── Listing-1-022.ts ├── Listing-1-023.ts ├── Listing-1-024.ts ├── Listing-1-025.js ├── Listing-1-025.ts ├── Listing-1-026.js ├── Listing-1-026.ts ├── Listing-1-027.js ├── Listing-1-027.ts ├── Listing-1-028.js ├── Listing-1-028.ts ├── Listing-1-029.js ├── Listing-1-029.ts ├── Listing-1-030.js ├── Listing-1-030.ts ├── Listing-1-031.js ├── Listing-1-031.ts ├── Listing-1-032.js ├── Listing-1-032.ts ├── Listing-1-033.js ├── Listing-1-033.ts ├── Listing-1-034.js ├── Listing-1-034.ts ├── Listing-1-035.js ├── Listing-1-035.ts ├── Listing-1-036.js ├── Listing-1-036.ts ├── Listing-1-037.js ├── Listing-1-037.ts ├── Listing-1-038.js ├── Listing-1-038.ts ├── Listing-1-039.js ├── Listing-1-039.ts ├── Listing-1-040.js ├── Listing-1-040.ts ├── Listing-1-041.js ├── Listing-1-041.ts ├── Listing-1-042.js ├── Listing-1-042.ts ├── Listing-1-043.js ├── Listing-1-043.ts ├── Listing-1-044.js ├── Listing-1-044.ts ├── Listing-1-045.js ├── Listing-1-045.ts ├── Listing-1-046.js ├── Listing-1-046.ts ├── Listing-1-047.js ├── Listing-1-047.ts ├── Listing-1-048.js ├── Listing-1-048.ts ├── Listing-1-049.js ├── Listing-1-049.ts ├── Listing-1-050.js ├── Listing-1-050.ts ├── Listing-1-051.js ├── Listing-1-051.ts ├── Listing-1-052.js ├── Listing-1-052.ts ├── Listing-1-053.js ├── Listing-1-053.ts ├── Listing-1-054.js ├── Listing-1-054.ts ├── Listing-1-055.js ├── Listing-1-055.ts ├── Listing-1-056.js ├── Listing-1-056.ts ├── Listing-1-057.js ├── Listing-1-057.ts ├── Listing-1-058.js ├── Listing-1-058.ts ├── Listing-1-059.js ├── Listing-1-059.ts ├── Listing-1-060.js ├── Listing-1-060.ts ├── Listing-1-061.js ├── Listing-1-061.ts ├── Listing-1-062.js ├── Listing-1-062.ts ├── Listing-1-063.js ├── Listing-1-063.ts ├── Listing-1-064.js ├── Listing-1-064.ts ├── Listing-1-065.js ├── Listing-1-065.ts ├── Listing-1-066.js ├── Listing-1-066.ts ├── Listing-1-067.js ├── Listing-1-067.ts ├── Listing-1-068.ts ├── Listing-1-069.js ├── Listing-1-069.ts ├── Listing-1-070.js ├── Listing-1-070.ts ├── Listing-1-071.js ├── Listing-1-071.ts ├── Listing-1-072.js ├── Listing-1-072.ts ├── Listing-1-073.js ├── Listing-1-073.ts ├── Listing-1-074.js ├── Listing-1-074.ts ├── Listing-1-075.js ├── Listing-1-075.ts ├── Listing-1-076.js ├── Listing-1-076.ts ├── Listing-1-077.js ├── Listing-1-077.ts ├── Listing-1-078.js ├── Listing-1-078.ts ├── Listing-1-079.js ├── Listing-1-079.ts ├── Listing-1-080.js ├── Listing-1-080.ts ├── Listing-1-081.js ├── Listing-1-081.ts ├── Listing-1-082.js ├── Listing-1-082.ts ├── Listing-1-083.js ├── Listing-1-083.ts ├── Listing-1-084.js ├── Listing-1-084.ts ├── Listing-1-085.js ├── Listing-1-085.ts ├── Listing-1-086.js ├── Listing-1-086.ts ├── Listing-1-087.js ├── Listing-1-087.ts ├── Listing-1-088.js ├── Listing-1-088.ts ├── Listing-1-089.js ├── Listing-1-089.ts ├── Listing-1-19.js ├── Listing-1-40.js └── obj │ └── Debug │ ├── Chapter01.csproj.CoreCompileInputs.cache │ ├── CoreCompileInputs.cache │ └── DesignTimeResolveAssemblyReferencesInput.cache ├── CH02 ├── .vs │ ├── Chapter02 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter02.csproj ├── Chapter02.csproj.user ├── Chapter02.sln ├── Figure-0-0.js ├── Figure-2-001.ts ├── Figure-2-002.txt ├── Listing-0-000-npm-including-types.js ├── Listing-1-001.js ├── Listing-1-002.js ├── Listing-2-000.ts ├── Listing-2-001.ts ├── Listing-2-002.ts ├── Listing-2-003.ts ├── Listing-2-004.ts ├── Listing-2-005.ts ├── Listing-2-006.ts ├── Listing-2-007.ts ├── Listing-2-008.ts ├── Listing-2-009.ts ├── Listing-2-010.ts ├── Listing-2-011.ts ├── Listing-2-012.ts ├── Listing-2-013.ts ├── Listing-2-014.ts ├── Listing-2-015.ts ├── Listing-2-016.ts ├── Listing-2-017.ts ├── Listing-2-018.ts ├── Listing-2-019.txt ├── Listing-2-020.txt ├── Listing-2-021.txt ├── Listing-2-022.txt ├── Listing-2-023.txt ├── Listing-2-024.ts ├── Listing-2-025.ts ├── Listing-2-026.ts ├── Listing-2-027.ts ├── Listing-2-028.ts ├── Shop │ └── Products │ │ └── ProductRepository.ts └── obj │ └── Debug │ ├── CH02.csproj.CoreCompileInputs.cache │ ├── Chapter02.csproj.CoreCompileInputs.cache │ ├── CoreCompileInputs.cache │ └── DesignTimeResolveAssemblyReferencesInput.cache ├── CH03 ├── .vs │ ├── Chapter03 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter03.csproj ├── Chapter03.csproj.user ├── Chapter03.sln ├── Listing-3-001.js ├── Listing-3-002.ts ├── Listing-3-003.js ├── Listing-3-003.ts ├── Listing-3-004.js ├── Listing-3-005.js ├── Listing-3-005.ts ├── Listing-3-006.js ├── Listing-3-006.ts ├── Listing-3-007.js ├── Listing-3-007.ts ├── Listing-3-008.js ├── Listing-3-008.ts ├── Listing-3-009.ts ├── Listing-3-010.js ├── Listing-3-010.ts ├── Listing-3-011.ts ├── Listing-3-012.js ├── Listing-3-012.ts ├── Listing-3-013.js ├── Listing-3-013.ts ├── Listing-3-014.js ├── Listing-3-014.ts ├── Listing-3-13.js └── obj │ └── Debug │ ├── Chapter03.csproj.CoreCompileInputs.cache │ └── DesignTimeResolveAssemblyReferencesInput.cache ├── CH04 ├── .vs │ ├── Chapter04 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter04.csproj ├── Chapter04.csproj.user ├── Chapter04.sln ├── Listing-4-001.ts ├── Listing-4-002.ts ├── Listing-4-003.ts ├── Listing-4-004.ts ├── Listing-4-005.ts ├── Listing-4-006.ts ├── Listing-4-007.ts ├── Listing-4-008.ts ├── Listing-4-009.ts ├── Listing-4-010.ts ├── Listing-4-011.ts ├── Listing-4-012.ts ├── Listing-4-013.ts ├── Listing-4-014.ts ├── Listing-4-015.ts ├── Listing-4-016.ts ├── Listing-4-017.ts ├── Listing-4-018.ts ├── Listing-4-019.ts ├── Listing-4-020.ts ├── Listing-4-021.ts ├── Listing-4-022.ts ├── Listing-4-023.ts ├── Listing-4-024.ts ├── Listing-4-025.ts ├── Listing_4_026.js ├── Listing_4_026.ts ├── obj │ └── Debug │ │ ├── Appendix01.csproj.CoreCompileInputs.cache │ │ ├── CoreCompileInputs.cache │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ └── DesignTimeResolveAssemblyReferencesInput.cache └── package.json ├── CH05 ├── .vs │ ├── Chapter05 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter05.csproj ├── Chapter05.csproj.user ├── Chapter05.sln ├── Listing-5-001.js ├── Listing-5-001.ts ├── Listing-5-002.js ├── Listing-5-002.ts ├── Listing-5-003.js ├── Listing-5-003.ts ├── Listing-5-004.js ├── Listing-5-004.ts ├── Listing-5-005.js ├── Listing-5-005.ts ├── Listing-5-006.js ├── Listing-5-007.js ├── Listing-5-007.ts ├── Listing-5-008.js ├── Listing-5-008.ts ├── Listing-5-009.js ├── Listing-5-009.ts ├── Listing-5-010.js ├── Listing-5-010.ts ├── Listing-5-011.js ├── Listing-5-011.ts ├── Listing-5-012.js ├── Listing-5-012.ts ├── Listing-5-013.js ├── Listing-5-013.ts ├── Listing-5-014--5-017.js ├── Listing-5-014--5-017.ts ├── Listing-5-014-CALLBACKS.js ├── Listing-5-014-CALLBACKSPLUSERRORS.js ├── Listing-5-014.js ├── Listing-5-015.js ├── Listing-5-016-PROMISES.js ├── Listing-5-016.js ├── Listing-5-018--5-021.js ├── Listing-5-018--5-021.ts ├── Listing-5-018-CALLBACKSPLUSERRORS.js ├── Listing-5-022--5-025.js ├── Listing-5-022--5-025.ts ├── Listing-5-022-PROMISES.js ├── Listing-5-026.js ├── Listing-5-026.ts ├── Listing-5-027.js ├── Listing-5-027.ts ├── Listing-5-028.js ├── Listing-5-028.ts ├── Listing-5-029.js ├── Listing-5-029.ts ├── Listing-5-030.js ├── Listing-5-030.ts ├── Listing-5-031.html ├── Listing-5-032.js ├── Listing-5-032.ts ├── Listing-5-033.js ├── Listing-5-033.ts ├── Listing-5-034.js ├── Listing-5-034.ts ├── Listing-5-035.js ├── Listing-5-035.ts ├── Listing-5-036.js ├── Listing-5-036.ts ├── Listing-5-037.js ├── Listing-5-037.ts ├── Listing-5-038.ts ├── Listing-5-039.ts ├── Listing-5-040.js ├── Listing-5-040.ts ├── Listing-5-041.js ├── Listing-5-041.ts ├── Listing-5-042.js ├── Listing-5-042.ts ├── Listing-5-1.js ├── Listing-5-2.js ├── Listing-5-3.js ├── Listing-5-4.js ├── Listing-5-5.js ├── obj │ └── Debug │ │ ├── Appendix01.csproj.CoreCompileInputs.cache │ │ ├── Chapter05.csproj.CoreCompileInputs.cache │ │ ├── CoreCompileInputs.cache │ │ └── DesignTimeResolveAssemblyReferencesInput.cache └── xListing-5-015 - Copy.js ├── CH06 ├── .vs │ ├── Chapter06 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter06.csproj ├── Chapter06.csproj.user ├── Chapter06.sln ├── Listing-5-033.js ├── Listing-6-001.ts ├── Listing-6-002.ts ├── Listing-6-003.html ├── Listing-6-004.ts ├── Listing-6-005.ts ├── Listing-6-006.ts ├── Listing-6-007.ts ├── Listing-6-008.ts ├── Listing-6-009.ts ├── Listing-6-010.ts ├── Listing-6-011.ts ├── Listing-6-012.ts ├── Listing-6-013.ts ├── Listing-6-014.ts ├── Listing-6-015.ts ├── Listing-6-016.ts ├── Listing-6-017.ts ├── Listing-6-018.ts ├── Listing-6-019.ts ├── Listing-6-020.ts ├── Listing-6-021.ts ├── Listing-6-022.ts ├── Listing-6-023.ts ├── Listing-6-024.ts ├── Listing-6-025.ts ├── Listing-6-026.html ├── Listing-6-027.ts ├── Listing-6-028.ts ├── Listing-6-029.ts ├── Listing-6-030.ts ├── Listing-6-031.ts ├── Listing-6-032.ts ├── Listing-6-033.ts ├── Listing-6-034.ts ├── Listing-6-035.ts ├── Listing-6-036.ts ├── Listing-6-037.ts ├── Listing-6-038.ts ├── Listing-6-039.ts ├── Listing-6-040.ts ├── Listing-6-041.ts ├── Listing-6-042.ts ├── Listing-6-043.ts ├── Listing-6-044.ts ├── Listing-6-045.ts ├── Listing-6-046.ts ├── WORKERS.html ├── obj │ └── Debug │ │ ├── Appendix01.csproj.CoreCompileInputs.cache │ │ ├── CoreCompileInputs.cache │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ └── DesignTimeResolveAssemblyReferencesInput.cache └── package.json ├── CH07 ├── .vs │ └── Chapter07 │ │ └── v15 │ │ └── .suo ├── Chapter07.sln └── NodeApp │ ├── Chapter07.njsproj │ ├── Chapter07.njsproj.user │ ├── README.md │ ├── obj │ └── Debug │ │ ├── Chapter07.njsproj.FileListAbsolute.txt │ │ ├── NodeApp.njsproj.CoreCompileInputs.cache │ │ ├── NodeApp.njsproj.FileListAbsolute.txt │ │ └── NodeApp.njsprojResolveAssemblyReference.cache │ ├── package.json │ ├── routes │ ├── book.ts │ └── index.ts │ ├── server.ts │ ├── style.css │ └── views │ ├── book.pug │ ├── index.pug │ └── layout.pug ├── CH08 ├── .vs │ ├── Chapter08 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter08.csproj ├── Chapter08.csproj.user ├── Chapter08.sln ├── Listing-8-001.js ├── Listing-8-001.ts ├── Listing-8-002.js ├── Listing-8-002.ts ├── Listing-8-003.js ├── Listing-8-003.ts ├── Listing-8-004.js ├── Listing-8-004.ts ├── Listing-8-005.js ├── Listing-8-005.ts ├── Listing-8-006.js ├── Listing-8-006.ts ├── Listing-8-007.ts ├── Listing-8-008.ts ├── Listing-8-009.js ├── Listing-8-009.ts ├── Listing-8-010.js ├── Listing-8-010.ts ├── Listing-8-011.js ├── Listing-8-011.ts ├── Listing-8-012.js ├── Listing-8-012.ts └── obj │ └── Debug │ ├── Appendix01.csproj.CoreCompileInputs.cache │ ├── Chapter08.csproj.CoreCompileInputs.cache │ ├── CoreCompileInputs.cache │ └── DesignTimeResolveAssemblyReferencesInput.cache ├── CH09 ├── .vs │ ├── Chapter9 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter9.csproj ├── Chapter9.csproj.user ├── Chapter9.sln ├── app.js ├── app.ts ├── dist │ ├── app.js │ ├── knockout.js │ ├── mynewlib.js │ └── myoldlib.js ├── index.html ├── knockout.d.ts ├── knockout.js ├── mynewlib.js ├── mynewlib.ts ├── myoldlib.js ├── obj │ └── Debug │ │ ├── Appendix01.csproj.CoreCompileInputs.cache │ │ ├── Chapter9.csproj.CoreCompileInputs.cache │ │ ├── CoreCompileInputs.cache │ │ └── DesignTimeResolveAssemblyReferencesInput.cache └── package.json ├── CH10 ├── .vs │ ├── Chapter10 │ │ └── v15 │ │ │ ├── .suo │ │ │ └── sqlite3 │ │ │ └── storage.ide │ └── config │ │ └── applicationhost.config ├── Chapter10.csproj ├── Chapter10.csproj.user ├── Chapter10.sln ├── FizzBuzz.test.ts ├── FizzBuzz.ts ├── npm-debug.log ├── obj │ └── Debug │ │ ├── Appendix01.csproj.CoreCompileInputs.cache │ │ ├── CoreCompileInputs.cache │ │ └── DesignTimeResolveAssemblyReferencesInput.cache └── package.json ├── LICENSE.txt ├── README.md └── contributing.md /A01/.vs/Appendix01/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/A01/.vs/Appendix01/v15/.suo -------------------------------------------------------------------------------- /A01/.vs/Appendix01/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/A01/.vs/Appendix01/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /A01/Listing-A1-001.js: -------------------------------------------------------------------------------- 1 | // Variable declaration 2 | 3 | let variable; 4 | 5 | // Variable assignment 6 | 7 | variable = 'A string is assigned'; 8 | 9 | // Dynamic assignment (changes variable’s type to a number) 10 | 11 | variable = 10; -------------------------------------------------------------------------------- /A01/Listing-A1-002.js: -------------------------------------------------------------------------------- 1 | // Creating an empty array and adding values 2 | 3 | const myArray = []; 4 | 5 | myArray.push(1); 6 | myArray.push(3); 7 | myArray.push(5); 8 | 9 | // Adding values using an array literal 10 | 11 | const myLiteralArray = [1, 3, 5]; -------------------------------------------------------------------------------- /A01/Listing-A1-003.js: -------------------------------------------------------------------------------- 1 | // Objects 2 | 3 | const myObject = {}; 4 | 5 | myObject.title = 'Example Object'; 6 | myObject.value = 5; 7 | 8 | // Object literals 9 | 10 | const myLiteralObject = { 11 | title: 'Example Object', 12 | value: 5 13 | }; -------------------------------------------------------------------------------- /A01/Listing-A1-004.js: -------------------------------------------------------------------------------- 1 | // Function declaration 2 | 3 | function myFunction(name) { 4 | return 'Hello ' + name; 5 | } 6 | 7 | // 'Hello Steve' 8 | let greeting = myFunction('Steve'); 9 | 10 | // Function expression 11 | 12 | var myFunctionExpression = function (name) { 13 | return 'Hi ' + name; 14 | }; 15 | 16 | // 'Hi Steve' 17 | greeting = myFunctionExpression('Steve'); -------------------------------------------------------------------------------- /A01/Listing-A1-005.js: -------------------------------------------------------------------------------- 1 | // If statements 2 | 3 | const age = 21; 4 | 5 | if (age > 18) { 6 | // Code to execute if age is greater than 18 7 | } 8 | 9 | if (age > 40) { 10 | // Code to execute if age is greater than 40 11 | } else if (age > 18) { 12 | // Code to execute if age is greater than 18 13 | // but less than 41 14 | } else { 15 | // Code to execute in all other cases 16 | } -------------------------------------------------------------------------------- /A01/Listing-A1-006.js: -------------------------------------------------------------------------------- 1 | // Switch statements 2 | 3 | const styles = { 4 | tranditional: 1, 5 | modern: 2, 6 | postModern: 3, 7 | futuristic: 4 8 | }; 9 | 10 | const style = styles.tranditional; 11 | 12 | switch (style) { 13 | case styles.tranditional: 14 | // Code to execute for traditional style 15 | break; 16 | case styles.modern: 17 | // Code to execute for modern style 18 | break; 19 | case styles.postModern: 20 | // Code to execute for post modern style 21 | break; 22 | case styles.futuristic: 23 | // Code to execute for futuristic style 24 | break; 25 | default: 26 | throw new Error('Style not known: ' + style); 27 | } -------------------------------------------------------------------------------- /A01/Listing-A1-007.js: -------------------------------------------------------------------------------- 1 | const names = ['Lily', 'Rebecca', 'Debbye', 'Ann']; 2 | 3 | for (let i = 0; i < names.length; i++) { 4 | console.log(names[i]); 5 | } -------------------------------------------------------------------------------- /A01/Listing-A1-008.js: -------------------------------------------------------------------------------- 1 | const names = ['Lily', 'Rebecca', 'Debbye', 'Ann']; 2 | 3 | for (let name in names) { 4 | console.log(name); 5 | } -------------------------------------------------------------------------------- /A01/Listing-A1-009.js: -------------------------------------------------------------------------------- 1 | let counter = 10; 2 | 3 | while (counter > 0) { 4 | counter--; 5 | console.log(counter); 6 | } -------------------------------------------------------------------------------- /A01/Listing-A1-010.js: -------------------------------------------------------------------------------- 1 | let counter = 0; 2 | 3 | do { 4 | counter--; 5 | console.log(counter); 6 | } while (counter > 0); -------------------------------------------------------------------------------- /A01/Listing-A1-011.js: -------------------------------------------------------------------------------- 1 | const name = 'Jamie'; 2 | 3 | // Traditional strings 4 | 5 | const classicString = 'Line One\n' + 6 | 'Line Two\n' + 7 | 'Line Three. Hello ' + name + '!'; 8 | 9 | // Back-ticked strings 10 | 11 | const backtickedString = `Line One 12 | Line Two 13 | Line Three. Hello ${name}!`; 14 | 15 | // 'Five plus seven is 12.' 16 | const expressionString = `Five plus seven is ${5 + 7}.`; -------------------------------------------------------------------------------- /A01/Listing-A1-012.js: -------------------------------------------------------------------------------- 1 | fetch('/Your/URL/').then(function (response) { 2 | // Response received 3 | if (response.status >= 200 && response.status < 300) { 4 | // We got a success status code 5 | } 6 | }).catch(function (error) { 7 | // Request failed 8 | }); -------------------------------------------------------------------------------- /A01/Listing-A1-013.js: -------------------------------------------------------------------------------- 1 | let promise = new Promise(function (resolve, reject) { 2 | window.setTimeout(function () { 3 | if (true) { 4 | resolve('Success'); 5 | } else { 6 | reject('Failed'); 7 | } 8 | }, 1000); 9 | }); 10 | 11 | promise.then(function (message) { 12 | alert(message); 13 | }).catch(function (error) { 14 | alert(error); 15 | }); -------------------------------------------------------------------------------- /A01/obj/Debug/Appendix01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /A01/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/A01/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /A02/app.ts: -------------------------------------------------------------------------------- 1 | import * as Dependency from './module'; 2 | 3 | export class Example extends Dependency.BaseClass { 4 | exampleMethod(): number { 5 | return 5; 6 | } 7 | } 8 | 9 | // Comment 10 | let example = new Example(); 11 | 12 | const val = example.exampleMethod(); -------------------------------------------------------------------------------- /A02/module.ts: -------------------------------------------------------------------------------- 1 | export class BaseClass { 2 | exampleMethod(): number { 3 | return 1; 4 | } 5 | } -------------------------------------------------------------------------------- /A03/.vs/Appendix03/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/A03/.vs/Appendix03/v15/.suo -------------------------------------------------------------------------------- /A03/.vs/Appendix03/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/A03/.vs/Appendix03/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /A03/Listing-A3-001.js: -------------------------------------------------------------------------------- 1 | var DiscFlags; 2 | (function (DiscFlags) { 3 | DiscFlags[DiscFlags["None"] = 0] = "None"; 4 | DiscFlags[DiscFlags["Drive"] = 1] = "Drive"; 5 | DiscFlags[DiscFlags["Influence"] = 2] = "Influence"; 6 | DiscFlags[DiscFlags["Steadiness"] = 4] = "Steadiness"; 7 | DiscFlags[DiscFlags["Conscientiousness"] = 8] = "Conscientiousness"; 8 | })(DiscFlags || (DiscFlags = {})); 9 | // Using flags 10 | var personality = DiscFlags.Drive | DiscFlags.Conscientiousness; 11 | // Testing flags 12 | // true 13 | var hasD = (personality & DiscFlags.Drive) == DiscFlags.Drive; 14 | // false 15 | var hasI = (personality & DiscFlags.Influence) == DiscFlags.Influence; 16 | // false 17 | var hasS = (personality & DiscFlags.Steadiness) == DiscFlags.Steadiness; 18 | // true 19 | var hasC = (personality & DiscFlags.Conscientiousness) == DiscFlags.Conscientiousness; 20 | -------------------------------------------------------------------------------- /A03/Listing-A3-001.ts: -------------------------------------------------------------------------------- 1 | enum DiscFlags { 2 | None = 0, 3 | Drive = 1 << 0, 4 | Influence = 1 << 1, 5 | Steadiness = 1 << 2, 6 | Conscientiousness = 1 << 3 7 | } 8 | // Using flags 9 | var personality = DiscFlags.Drive | DiscFlags.Conscientiousness; 10 | 11 | // Testing flags 12 | 13 | // true 14 | var hasD = (personality & DiscFlags.Drive) == DiscFlags.Drive; 15 | 16 | // false 17 | var hasI = (personality & DiscFlags.Influence) == DiscFlags.Influence; 18 | 19 | // false 20 | var hasS = (personality & DiscFlags.Steadiness) == DiscFlags.Steadiness; 21 | 22 | // true 23 | var hasC = (personality & DiscFlags.Conscientiousness) == DiscFlags.Conscientiousness; 24 | -------------------------------------------------------------------------------- /A03/Listing-A3-002.js: -------------------------------------------------------------------------------- 1 | // Both personalityA and personalityB include DiscFlags.Influence 2 | var personalityA = DiscFlags.Drive | DiscFlags.Influence | DiscFlags.Conscientiousness; 3 | var personalityB = DiscFlags.Influence | DiscFlags.Steadiness; 4 | // The result of a bitwise AND contains only matching flags 5 | // DiscFlags.Influence 6 | var matchingTraits = personalityA & personalityB; 7 | // false 8 | var hasD = (matchingTraits & DiscFlags.Drive) == DiscFlags.Drive; 9 | // true 10 | var hasI = (matchingTraits & DiscFlags.Influence) == DiscFlags.Influence; 11 | // false 12 | var hasS = (matchingTraits & DiscFlags.Steadiness) == DiscFlags.Steadiness; 13 | // false 14 | var hasC = (matchingTraits & DiscFlags.Conscientiousness) == DiscFlags.Conscientiousness; 15 | -------------------------------------------------------------------------------- /A03/Listing-A3-002.ts: -------------------------------------------------------------------------------- 1 | // Both personalityA and personalityB include DiscFlags.Influence 2 | var personalityA = DiscFlags.Drive | DiscFlags.Influence | DiscFlags.Conscientiousness; 3 | var personalityB = DiscFlags.Influence | DiscFlags.Steadiness; 4 | 5 | // The result of a bitwise AND contains only matching flags 6 | 7 | // DiscFlags.Influence 8 | var matchingTraits = personalityA & personalityB; 9 | 10 | // false 11 | var hasD = (matchingTraits & DiscFlags.Drive) == DiscFlags.Drive; 12 | 13 | // true 14 | var hasI = (matchingTraits & DiscFlags.Influence) == DiscFlags.Influence; 15 | 16 | // false 17 | var hasS = (matchingTraits & DiscFlags.Steadiness) == DiscFlags.Steadiness; 18 | 19 | // false 20 | var hasC = (matchingTraits & DiscFlags.Conscientiousness) == DiscFlags.Conscientiousness; 21 | -------------------------------------------------------------------------------- /A03/obj/Debug/Appendix03.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /A03/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/A03/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH01/.vs/Chapter01/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH01/.vs/Chapter01/v15/.suo -------------------------------------------------------------------------------- /CH01/.vs/Chapter01/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH01/.vs/Chapter01/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH01/Figure-1-001.ts: -------------------------------------------------------------------------------- 1 | let radius = 4; 2 | const area = Math.PI * radius * radius; 3 | 4 | radius = 'A string' -------------------------------------------------------------------------------- /CH01/Figure-1-002.ts: -------------------------------------------------------------------------------- 1 | { 2 | let radius = 4; 3 | 4 | radius. 5 | } -------------------------------------------------------------------------------- /CH01/Listing-1-001.js: -------------------------------------------------------------------------------- 1 | // Not using with 2 | const radius1 = 4; 3 | const area1 = Math.PI * radius1 * radius1; 4 | 5 | // Using with 6 | const radius2 = 4; 7 | with (Math) { 8 | const area2 = PI * radius2 * radius2; 9 | } 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-002.js: -------------------------------------------------------------------------------- 1 | { 2 | var radius_1 = 4; 3 | var area_1 = Math.PI * radius_1 * radius_1; 4 | } 5 | -------------------------------------------------------------------------------- /CH01/Listing-1-002.ts: -------------------------------------------------------------------------------- 1 | { 2 | const radius = 4; 3 | const area = Math.PI * radius * radius; 4 | } -------------------------------------------------------------------------------- /CH01/Listing-1-003.ts: -------------------------------------------------------------------------------- 1 | let globalScope = 1; 2 | 3 | { 4 | let blockScope = 2; 5 | 6 | // OK. This is from a wider scope 7 | globalScope = 100; 8 | 9 | // Error! This is from a narrower scope 10 | nestedBlockScope = 300; 11 | 12 | { 13 | let nestedBlockScope = 3; 14 | 15 | // OK. This is from a wider scope 16 | globalScope = 1000; 17 | 18 | // OK. This is from a wider scope 19 | blockScope = 2000; 20 | } 21 | } -------------------------------------------------------------------------------- /CH01/Listing-1-004.js: -------------------------------------------------------------------------------- 1 | { 2 | var firstName_1 = 'Chris'; 3 | { 4 | var firstName_2 = 'Tudor'; 5 | console.log('Name 1: ' + firstName_2); 6 | } 7 | console.log('Name 2: ' + firstName_1); 8 | // Output: 9 | // Name 1: Tudor 10 | // Name 2: Chris 11 | } 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-004.ts: -------------------------------------------------------------------------------- 1 | { 2 | let firstName = 'Chris'; 3 | 4 | { 5 | let firstName = 'Tudor'; 6 | 7 | console.log('Name 1: ' + firstName); 8 | } 9 | 10 | console.log('Name 2: ' + firstName); 11 | 12 | // Output: 13 | // Name 1: Tudor 14 | // Name 2: Chris 15 | } -------------------------------------------------------------------------------- /CH01/Listing-1-005.js: -------------------------------------------------------------------------------- 1 | var firstName = 'Chris'; 2 | { 3 | var firstName = 'Tudor'; 4 | console.log('Name 1: ' + firstName); 5 | } 6 | console.log('Name 2: ' + firstName); 7 | // Output: 8 | // Name 1: Tudor 9 | // Name 2: Tudor 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-005.ts: -------------------------------------------------------------------------------- 1 | var firstName = 'Chris'; 2 | 3 | { 4 | var firstName = 'Tudor'; 5 | 6 | console.log('Name 1: ' + firstName); 7 | } 8 | 9 | console.log('Name 2: ' + firstName); 10 | 11 | // Output: 12 | // Name 1: Tudor 13 | // Name 2: Tudor -------------------------------------------------------------------------------- /CH01/Listing-1-006.ts: -------------------------------------------------------------------------------- 1 | { 2 | const name = 'Lily'; 3 | 4 | // Error! Cannot assign to name because it is a constant 5 | name = 'Princess Sparkles'; 6 | 7 | const digits = [1, 2, 3]; 8 | 9 | // Mutable - this changes the value of digits without using an assignment 10 | digits.push(4, 5, 6); 11 | } -------------------------------------------------------------------------------- /CH01/Listing-1-007.ts: -------------------------------------------------------------------------------- 1 | const name: string = 'Steve'; -------------------------------------------------------------------------------- /CH01/Listing-1-008.js: -------------------------------------------------------------------------------- 1 | { 2 | // primitive type annotation 3 | var name_1 = 'Steve'; 4 | var heightInCentimeters = 182.88; 5 | var isActive = true; 6 | // array type annotation 7 | var names = ['James', 'Nick', 'Rebecca', 'Lily']; 8 | // function annotation with parameter type annotation and return type annotation 9 | var sayHello = void 0; 10 | // implementation of sayHello function 11 | sayHello = function (name) { 12 | return 'Hello ' + name; 13 | }; 14 | // object type annotation 15 | var person = void 0; 16 | // Implementation of a person object 17 | person = { 18 | name: 'Mark', 19 | heightInCentimeters: 183 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /CH01/Listing-1-008.ts: -------------------------------------------------------------------------------- 1 | { 2 | // primitive type annotation 3 | const name: string = 'Steve'; 4 | const heightInCentimeters: number = 182.88; 5 | const isActive: boolean = true; 6 | 7 | // array type annotation 8 | const names: string[] = ['James', 'Nick', 'Rebecca', 'Lily']; 9 | 10 | // function annotation with parameter type annotation and return type annotation 11 | let sayHello: (name: string) => string; 12 | 13 | 14 | // implementation of sayHello function 15 | sayHello = function (name) { 16 | return 'Hello ' + name; 17 | }; 18 | 19 | // object type annotation 20 | let person: { name: string; heightInCentimeters: number; }; 21 | 22 | // Implementation of a person object 23 | person = { 24 | name: 'Mark', 25 | heightInCentimeters: 183 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /CH01/Listing-1-009.js: -------------------------------------------------------------------------------- 1 | var sherlock = { 2 | name: 'Bendict', 3 | heightInCentimeters: 183 4 | }; 5 | var john = { 6 | name: 'Martin', 7 | heightInCentimeters: 169 8 | }; 9 | -------------------------------------------------------------------------------- /CH01/Listing-1-009.ts: -------------------------------------------------------------------------------- 1 | // Interface 2 | interface PersonInterface { 3 | name: string; 4 | heightInCentimeters: number; 5 | } 6 | 7 | const sherlock: PersonInterface = { 8 | name: 'Bendict', 9 | heightInCentimeters: 183 10 | } 11 | 12 | // Type Alias 13 | type PersonType = { 14 | name: string; 15 | heightInCentimeters: number; 16 | }; 17 | 18 | const john: PersonType = { 19 | name: 'Martin', 20 | heightInCentimeters: 169 21 | } -------------------------------------------------------------------------------- /CH01/Listing-1-010.js: -------------------------------------------------------------------------------- 1 | { 2 | var VehicleType_1 = void 0; 3 | (function (VehicleType) { 4 | VehicleType[VehicleType["PedalCycle"] = 0] = "PedalCycle"; 5 | VehicleType[VehicleType["MotorCycle"] = 1] = "MotorCycle"; 6 | VehicleType[VehicleType["Car"] = 2] = "Car"; 7 | VehicleType[VehicleType["Van"] = 3] = "Van"; 8 | VehicleType[VehicleType["Bus"] = 4] = "Bus"; 9 | VehicleType[VehicleType["Lorry"] = 5] = "Lorry"; 10 | })(VehicleType_1 || (VehicleType_1 = {})); 11 | var type_1 = VehicleType_1.Lorry; 12 | var typeName = VehicleType_1[type_1]; // 'Lorry' 13 | } 14 | -------------------------------------------------------------------------------- /CH01/Listing-1-010.ts: -------------------------------------------------------------------------------- 1 | { 2 | enum VehicleType { 3 | PedalCycle, 4 | MotorCycle, 5 | Car, 6 | Van, 7 | Bus, 8 | Lorry 9 | } 10 | 11 | const type = VehicleType.Lorry; 12 | 13 | const typeName = VehicleType[type]; // 'Lorry' 14 | } -------------------------------------------------------------------------------- /CH01/Listing-1-011.js: -------------------------------------------------------------------------------- 1 | var BoxSize; 2 | (function (BoxSize) { 3 | BoxSize[BoxSize["Small"] = 0] = "Small"; 4 | BoxSize[BoxSize["Medium"] = 1] = "Medium"; 5 | })(BoxSize || (BoxSize = {})); 6 | //... 7 | (function (BoxSize) { 8 | BoxSize[BoxSize["Large"] = 2] = "Large"; 9 | BoxSize[BoxSize["XLarge"] = 3] = "XLarge"; 10 | BoxSize[BoxSize["XXLarge"] = 4] = "XXLarge"; 11 | })(BoxSize || (BoxSize = {})); 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-011.ts: -------------------------------------------------------------------------------- 1 | enum BoxSize { 2 | Small, 3 | Medium 4 | } 5 | 6 | //... 7 | 8 | enum BoxSize { 9 | Large = 2, 10 | XLarge, 11 | XXLarge 12 | } -------------------------------------------------------------------------------- /CH01/Listing-1-012.js: -------------------------------------------------------------------------------- 1 | var DiscFlags; 2 | (function (DiscFlags) { 3 | DiscFlags[DiscFlags["None"] = 0] = "None"; 4 | DiscFlags[DiscFlags["Drive"] = 1] = "Drive"; 5 | DiscFlags[DiscFlags["Influence"] = 2] = "Influence"; 6 | DiscFlags[DiscFlags["Steadiness"] = 4] = "Steadiness"; 7 | DiscFlags[DiscFlags["Conscientiousness"] = 8] = "Conscientiousness"; 8 | })(DiscFlags || (DiscFlags = {})); 9 | // Using flags 10 | var personality = DiscFlags.Drive | DiscFlags.Conscientiousness; 11 | // Testing flags 12 | // true 13 | var hasD = (personality & DiscFlags.Drive) == DiscFlags.Drive; 14 | // false 15 | var hasI = (personality & DiscFlags.Influence) == DiscFlags.Influence; 16 | // false 17 | var hasS = (personality & DiscFlags.Steadiness) == DiscFlags.Steadiness; 18 | // true 19 | var hasC = (personality & DiscFlags.Conscientiousness) == DiscFlags.Conscientiousness; 20 | -------------------------------------------------------------------------------- /CH01/Listing-1-012.ts: -------------------------------------------------------------------------------- 1 | enum DiscFlags { 2 | None = 0, 3 | Drive = 1, 4 | Influence = 2, 5 | Steadiness = 4, 6 | Conscientiousness = 8 7 | } 8 | 9 | // Using flags 10 | var personality = DiscFlags.Drive | DiscFlags.Conscientiousness; 11 | 12 | // Testing flags 13 | 14 | // true 15 | var hasD = (personality & DiscFlags.Drive) == DiscFlags.Drive; 16 | 17 | // false 18 | var hasI = (personality & DiscFlags.Influence) == DiscFlags.Influence; 19 | 20 | // false 21 | var hasS = (personality & DiscFlags.Steadiness) == DiscFlags.Steadiness; 22 | 23 | // true 24 | var hasC = (personality & DiscFlags.Conscientiousness) == DiscFlags.Conscientiousness; 25 | -------------------------------------------------------------------------------- /CH01/Listing-1-013.js: -------------------------------------------------------------------------------- 1 | var type = 5 /* Lorry */; 2 | -------------------------------------------------------------------------------- /CH01/Listing-1-013.ts: -------------------------------------------------------------------------------- 1 | const enum VehicleType { 2 | PedalCycle, 3 | MotorCycle, 4 | Car, 5 | Van, 6 | Bus, 7 | Lorry 8 | } 9 | 10 | const type = VehicleType.Lorry; -------------------------------------------------------------------------------- /CH01/Listing-1-014.js: -------------------------------------------------------------------------------- 1 | var type = 5 /* Lorry */; -------------------------------------------------------------------------------- /CH01/Listing-1-015.ts: -------------------------------------------------------------------------------- 1 | // Type annotation for a union type 2 | let union: boolean | number; 3 | 4 | // OK: number 5 | union = 5; 6 | 7 | // OK: boolean 8 | union = true; 9 | 10 | // Error: Type "string" is not assignable to type 'number | boolean' 11 | union = 'string'; 12 | 13 | // Type alias for a union type 14 | type StringOrError = string | Error; 15 | 16 | // Type alias for union of many types 17 | type SeriesOfTypes = string | number | boolean | Error; -------------------------------------------------------------------------------- /CH01/Listing-1-016.ts: -------------------------------------------------------------------------------- 1 | { 2 | type Kingdom = 'Bacteria' | 'Protozoa' | 'Chromista' | 'Plantae' | 'Fungi' | 'Animalia'; 3 | 4 | let kingdom: Kingdom; 5 | 6 | // OK 7 | kingdom = 'Bacteria'; 8 | 9 | // Error: Type 'Protista' is not assignable to type 'Kingdom' 10 | kingdom = 'Protista'; 11 | } -------------------------------------------------------------------------------- /CH01/Listing-1-017.ts: -------------------------------------------------------------------------------- 1 | { 2 | // Number literal type 3 | type Fibonacci = 1 | 2 | 3 | 5 | 8 | 13; 4 | 5 | let num: Fibonacci; 6 | 7 | // OK 8 | num = 8; 9 | 10 | // Error: Type '9' is not assignable to type 'Fibonacci' 11 | num = 9; 12 | 13 | // Hybrid union/literal type 14 | type Randoms = 'Text' | 10 | false; 15 | 16 | let random: Randoms; 17 | 18 | // OK 19 | random = 'Text'; 20 | random = 10; 21 | random = false; 22 | 23 | // Error: Not assignable. 24 | random = 'Other String'; 25 | random = 12; 26 | random = true; 27 | } -------------------------------------------------------------------------------- /CH01/Listing-1-018.ts: -------------------------------------------------------------------------------- 1 | interface Skier { 2 | slide(): void; 3 | } 4 | 5 | interface Shooter { 6 | shoot(): void; 7 | } 8 | 9 | type Biathelete = Skier & Shooter; -------------------------------------------------------------------------------- /CH01/Listing-1-019.js: -------------------------------------------------------------------------------- 1 | // The array is typed using the Monument interface 2 | var monuments = []; 3 | // Each item added to the array is checked for type compatibility 4 | monuments.push({ 5 | name: 'Statue of Liberty', 6 | heightInMeters: 46 7 | }); 8 | monuments.push({ 9 | name: 'Peter the Great', 10 | heightInMeters: 96 11 | }); 12 | monuments.push({ 13 | name: 'Angel of the North', 14 | heightInMeters: 20 15 | }); 16 | function compareMonumentHeights(a, b) { 17 | if (a.heightInMeters > b.heightInMeters) { 18 | return -1; 19 | } 20 | if (a.heightInMeters < b.heightInMeters) { 21 | return 1; 22 | } 23 | return 0; 24 | } 25 | // The array.sort method expects a comparer that accepts two Monuments 26 | var monumentsOrderedByHeight = monuments.sort(compareMonumentHeights); 27 | // Get the first element from the array, which is the tallest 28 | var tallestMonument = monumentsOrderedByHeight[0]; 29 | // Peter the Great 30 | console.log(tallestMonument.name); 31 | -------------------------------------------------------------------------------- /CH01/Listing-1-020.js: -------------------------------------------------------------------------------- 1 | var tuple; 2 | // OK 3 | tuple = ['my', true, 1]; 4 | // Error: 5 | tuple = [1, 1, 1]; 6 | -------------------------------------------------------------------------------- /CH01/Listing-1-020.ts: -------------------------------------------------------------------------------- 1 | let poem: [number , boolean , string]; 2 | 3 | // OK 4 | poem = [1, true, 'love']; 5 | 6 | // Error: 'string' is not assignable to 'number' 7 | poem = ['my', true, 'love']; 8 | 9 | poem[2]. -------------------------------------------------------------------------------- /CH01/Listing-1-021.ts: -------------------------------------------------------------------------------- 1 | interface Cephalopod { 2 | hasInk: boolean; 3 | arms: number; 4 | tentacles: number; 5 | } 6 | 7 | interface CephalopodDictionary { 8 | [index: string]: Cephalopod; 9 | } 10 | 11 | let dictionary: CephalopodDictionary = {}; 12 | 13 | dictionary['octopus vulgaris'] = { hasInk: true, arms: 8, tentacles: 0 }; 14 | dictionary['loligo vulgaris'] = { hasInk: true, arms: 8, tentacles: 2 }; 15 | 16 | // Error. Not assignable to type 'Cephalopod' 17 | dictionary[0] = { hasInk: true }; 18 | 19 | const octopus = dictionary['octopus vulgaris']; 20 | 21 | // The common octopus has no tentacles... 22 | console.log(octopus.tentacles); 23 | 24 | // Remove item 25 | delete dictionary['octopus vulgaris']; -------------------------------------------------------------------------------- /CH01/Listing-1-022.ts: -------------------------------------------------------------------------------- 1 | namespace Options_1 { 2 | interface Options { 3 | material: string; 4 | backlight: boolean; 5 | } 6 | 7 | // Manually created readonly interface 8 | interface ManualReadonlyOptions { 9 | readonly material: string; 10 | readonly backlight: boolean; 11 | } 12 | 13 | // Manually created optional interface 14 | interface ManualOptionalOptions { 15 | material?: string; 16 | backlight?: string; 17 | } 18 | 19 | // Manually created nullable interface 20 | interface ManualNullableOptions { 21 | material: string | null; 22 | backlight: string | null; 23 | } 24 | } -------------------------------------------------------------------------------- /CH01/Listing-1-023.ts: -------------------------------------------------------------------------------- 1 | interface Options { 2 | material: string; 3 | backlight: boolean; 4 | } 5 | 6 | // Mapped types 7 | type ReadOnly = { readonly [k in keyof T]: T[k]; } 8 | type Optional = {[k in keyof T]?: T[k]; } 9 | type Nullable = {[k in keyof T]: T[k] | null; } 10 | 11 | // Creating new types from mapped types 12 | type ReadonlyOptions = Readonly; 13 | type OptionalOptions = Optional; 14 | type NullableOptions = Nullable; -------------------------------------------------------------------------------- /CH01/Listing-1-024.ts: -------------------------------------------------------------------------------- 1 | // Read-only type 2 | const options1: ReadonlyOptions = { 3 | backlight: true, 4 | material: 'plastic' 5 | }; 6 | 7 | // Error. Property is read-only 8 | options1.backlight = false; 9 | 10 | // Optional type 11 | const options2: OptionalOptions = { 12 | // All members are optional 13 | }; 14 | 15 | // Nullable type 16 | const options3: NullableOptions = { 17 | backlight: null, 18 | material: null 19 | }; -------------------------------------------------------------------------------- /CH01/Listing-1-025.js: -------------------------------------------------------------------------------- 1 | function volume(prism) { 2 | // Type Guard 3 | switch (prism.kind) { 4 | case 'cube': 5 | return prism.size * prism.size * prism.size; 6 | case 'cuboid': 7 | return prism.width * prism.depth * prism.height; 8 | default: 9 | assertNever(prism); 10 | break; 11 | } 12 | } 13 | function assertNever(arg) { 14 | throw new Error("Possible new tagged type: " + arg); 15 | } 16 | -------------------------------------------------------------------------------- /CH01/Listing-1-025.ts: -------------------------------------------------------------------------------- 1 | interface House { 2 | bedrooms: number; 3 | bathrooms: number; 4 | } 5 | 6 | interface Mansion { 7 | bedrooms: number; 8 | bathrooms: number; 9 | butlers: number; 10 | } 11 | 12 | function getProperty() : House | Mansion { 13 | // ... 14 | } 15 | 16 | const property = getProperty(); 17 | 18 | // OK as the property is on both House and Mansion 19 | const bedroomCount = property.bedrooms; 20 | 21 | // Errors: Property 'butlers' does not exist on type 'House | Mansion' 22 | const butlerCount = property.butlers; 23 | 24 | // OK with type assertion 25 | const workingButlerCount = (property).butlers; -------------------------------------------------------------------------------- /CH01/Listing-1-026.js: -------------------------------------------------------------------------------- 1 | function volume(prism) { 2 | // Type Guard 3 | switch (prism.kind) { 4 | case 'cube': 5 | return prism.size * prism.size * prism.size; 6 | case 'cuboid': 7 | return prism.width * prism.depth * prism.height; 8 | default: 9 | assertNever(prism); 10 | break; 11 | } 12 | } 13 | function assertNever(arg) { 14 | throw new Error("Possible new tagged type: " + arg); 15 | } 16 | -------------------------------------------------------------------------------- /CH01/Listing-1-026.ts: -------------------------------------------------------------------------------- 1 | { 2 | const name: string = 'Avenue Road'; 3 | 4 | // Error: Type 'string' cannot be converted to type 'number' 5 | const bedroomCount: number = name; 6 | 7 | // Works 8 | const workingBedroomCount: number = name; 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-027.js: -------------------------------------------------------------------------------- 1 | var counter = 0; 2 | do { 3 | ++counter; 4 | } while (counter < 10); 5 | // 10 6 | alert(counter); 7 | -------------------------------------------------------------------------------- /CH01/Listing-1-027.ts: -------------------------------------------------------------------------------- 1 | function typeGuardExample(stringNumber: string | number) { 2 | // Error: Property does not exist 3 | const a = stringNumber.length; 4 | const b = stringNumber.toFixed(); 5 | 6 | // Type guard 7 | if (typeof stringNumber === 'string') { 8 | // OK 9 | return stringNumber.length; 10 | } else { 11 | // OK 12 | return stringNumber.toFixed(); 13 | } 14 | } -------------------------------------------------------------------------------- /CH01/Listing-1-028.js: -------------------------------------------------------------------------------- 1 | var Size; 2 | (function (Size) { 3 | Size[Size["S"] = 0] = "S"; 4 | Size[Size["M"] = 1] = "M"; 5 | Size[Size["L"] = 2] = "L"; 6 | Size[Size["XL"] = 3] = "XL"; 7 | })(Size || (Size = {})); 8 | var size; 9 | size = Size.S; 10 | ++size; 11 | console.log(Size[size]); // M 12 | size = Size.XL; 13 | --size; 14 | console.log(Size[size]); // L 15 | size = Size.XL; 16 | ++size; 17 | console.log(Size[size]); // undefined 18 | -------------------------------------------------------------------------------- /CH01/Listing-1-028.ts: -------------------------------------------------------------------------------- 1 | interface SpeedControllable { 2 | increaseSpeed(): void; 3 | decreaseSpeed(): void; 4 | stop(): void; 5 | } 6 | 7 | interface InclineControllable { 8 | lift(): void; 9 | drop(): void; 10 | } 11 | 12 | function isSpeedControllable(treadmill: SpeedControllable | any): treadmill is SpeedControllable { 13 | if (treadmill.increaseSpeed 14 | && treadmill.decreaseSpeed 15 | && treadmill.stop) { 16 | return true; 17 | } 18 | 19 | return false; 20 | } 21 | 22 | function customTypeGuardExample(treadmill: SpeedControllable | InclineControllable) { 23 | // Error: Property does not exist 24 | const a = treadmill.increaseSpeed(); 25 | const b = treadmill.lift(); 26 | 27 | // Type guard 28 | if (isSpeedControllable(treadmill)) { 29 | // OK 30 | treadmill.increaseSpeed(); 31 | } else { 32 | // OK 33 | treadmill.lift(); 34 | } 35 | } -------------------------------------------------------------------------------- /CH01/Listing-1-029.js: -------------------------------------------------------------------------------- 1 | function volume(prism) { 2 | // Type Guard 3 | switch (prism.kind) { 4 | case 'cube': 5 | return prism.size * prism.size * prism.size; 6 | case 'cuboid': 7 | return prism.width * prism.depth * prism.height; 8 | default: 9 | assertNever(prism); 10 | break; 11 | } 12 | } 13 | function assertNever(arg) { 14 | throw new Error("Possible new tagged type: " + arg); 15 | } 16 | -------------------------------------------------------------------------------- /CH01/Listing-1-029.ts: -------------------------------------------------------------------------------- 1 | interface Cube { 2 | kind: 'cube'; // Discriminant 3 | size: number; 4 | } 5 | 6 | interface Cuboid { 7 | kind: 'cuboid'; // Discriminant 8 | width: number; 9 | depth: number; 10 | height: number; 11 | } 12 | 13 | // Union 14 | type Prism = Cube | Cuboid; 15 | 16 | function volume(prism: Prism): number { 17 | // Type Guard 18 | switch (prism.kind) { 19 | case 'cube': 20 | return prism.size * prism.size * prism.size; 21 | case 'cuboid': 22 | return prism.width * prism.depth * prism.height; 23 | default: 24 | assertNever(prism); 25 | break; 26 | } 27 | } 28 | 29 | function assertNever(arg: never): never { 30 | throw new Error("Possible new tagged type: " + arg); 31 | } -------------------------------------------------------------------------------- /CH01/Listing-1-030.js: -------------------------------------------------------------------------------- 1 | var counter = 0; 2 | do { 3 | ++counter; 4 | } while (counter < 10); 5 | // 10 6 | alert(counter); 7 | -------------------------------------------------------------------------------- /CH01/Listing-1-030.ts: -------------------------------------------------------------------------------- 1 | let counter = 0; 2 | 3 | do { 4 | ++counter; 5 | } while (counter < 10); 6 | 7 | // 10 8 | alert(counter); -------------------------------------------------------------------------------- /CH01/Listing-1-031.js: -------------------------------------------------------------------------------- 1 | var Size; 2 | (function (Size) { 3 | Size[Size["S"] = 0] = "S"; 4 | Size[Size["M"] = 1] = "M"; 5 | Size[Size["L"] = 2] = "L"; 6 | Size[Size["XL"] = 3] = "XL"; 7 | })(Size || (Size = {})); 8 | var size; 9 | size = Size.S; 10 | ++size; 11 | console.log(Size[size]); // M 12 | size = Size.XL; 13 | --size; 14 | console.log(Size[size]); // L 15 | size = Size.XL; 16 | ++size; 17 | console.log(Size[size]); // undefined 18 | -------------------------------------------------------------------------------- /CH01/Listing-1-031.ts: -------------------------------------------------------------------------------- 1 | enum Size { 2 | S, 3 | M, 4 | L, 5 | XL 6 | } 7 | 8 | let size: Size; 9 | 10 | size = Size.S; 11 | ++size; 12 | console.log(Size[size]); // M 13 | 14 | size = Size.XL; 15 | --size; 16 | console.log(Size[size]); // L 17 | 18 | size = Size.XL; 19 | ++size; 20 | console.log(Size[size]); // undefined -------------------------------------------------------------------------------- /CH01/Listing-1-032.js: -------------------------------------------------------------------------------- 1 | // 6: number 2 | var num = 5 + 1; 3 | // '51': string 4 | var str = 5 + '1'; 5 | -------------------------------------------------------------------------------- /CH01/Listing-1-032.ts: -------------------------------------------------------------------------------- 1 | // 6: number 2 | const num = 5 + 1; 3 | 4 | // '51': string 5 | const str = 5 + '1'; -------------------------------------------------------------------------------- /CH01/Listing-1-033.js: -------------------------------------------------------------------------------- 1 | { 2 | var str_1 = '5'; 3 | // 5: number 4 | var num_1 = +str_1; 5 | // -5: number 6 | var negative = -str_1; 7 | } 8 | -------------------------------------------------------------------------------- /CH01/Listing-1-033.ts: -------------------------------------------------------------------------------- 1 | { 2 | const str: string = '5'; 3 | 4 | // 5: number 5 | const num = +str; 6 | 7 | // -5: number 8 | const negative = -str; 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-034.js: -------------------------------------------------------------------------------- 1 | var truthyString = 'Truthy string'; 2 | var falseyString; 3 | // False, it checks the string but inverts the truth 4 | var invertedTest = !truthyString; 5 | // True, the string is not undefined or empty 6 | var truthyTest = !!truthyString; 7 | // False, the string is empty 8 | var falseyTest = !!falseyString; 9 | -------------------------------------------------------------------------------- /CH01/Listing-1-034.ts: -------------------------------------------------------------------------------- 1 | const truthyString = 'Truthy string'; 2 | let falseyString: string; 3 | 4 | // False, it checks the string but inverts the truth 5 | const invertedTest = !truthyString; 6 | 7 | // True, the string is not undefined or empty 8 | const truthyTest = !!truthyString; 9 | 10 | // False, the string is empty 11 | const falseyTest = !!falseyString; -------------------------------------------------------------------------------- /CH01/Listing-1-035.js: -------------------------------------------------------------------------------- 1 | var myProperty; 2 | if (myProperty) { 3 | // Reaching this location means that... 4 | // myProperty is not null 5 | // myProperty is not undefined 6 | // myProperty is not boolean false 7 | // myProperty is not an empty string 8 | // myProperty is not the number 0 9 | // myProperty is not NaN 10 | } 11 | -------------------------------------------------------------------------------- /CH01/Listing-1-035.ts: -------------------------------------------------------------------------------- 1 | var myProperty; 2 | 3 | if (myProperty) { 4 | // Reaching this location means that... 5 | // myProperty is not null 6 | // myProperty is not undefined 7 | // myProperty is not boolean false 8 | // myProperty is not an empty string 9 | // myProperty is not the number 0 10 | // myProperty is not NaN 11 | } -------------------------------------------------------------------------------- /CH01/Listing-1-036.js: -------------------------------------------------------------------------------- 1 | // longhand 2 | if (console) { 3 | console.log('Console Available'); 4 | } 5 | // shorthand 6 | console && console.log('Console Available'); 7 | var player1 = 'Martin'; 8 | // player2 is only defined if player1 is defined 9 | var player2 = player1 && 'Dan'; 10 | // 'Dan' 11 | alert(player2); 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-036.ts: -------------------------------------------------------------------------------- 1 | // longhand 2 | if (console) { 3 | console.log('Console Available'); 4 | } 5 | 6 | // shorthand 7 | console && console.log('Console Available'); 8 | 9 | const player1 = 'Martin'; 10 | 11 | // player2 is only defined if player1 is defined 12 | const player2 = player1 && 'Dan'; 13 | 14 | // 'Dan' 15 | alert(player2); -------------------------------------------------------------------------------- /CH01/Listing-1-037.js: -------------------------------------------------------------------------------- 1 | // Empty strings are falsey 2 | var errorMessages = ''; 3 | // result is 'Saved OK' 4 | var result = errorMessages || 'Saved OK'; 5 | // Filled strings are truthy 6 | errorMessages = 'Error Detected'; 7 | // result is 'Error Detected' 8 | result = errorMessages || 'Saved OK'; 9 | var undefinedLogger; 10 | // if the logger isn't initialized, substitute it for the result of the right-hand expression 11 | var logger = undefinedLogger || { log: function (msg) { alert(msg); } }; 12 | // alerts 'Message' 13 | logger.log('Message'); 14 | -------------------------------------------------------------------------------- /CH01/Listing-1-037.ts: -------------------------------------------------------------------------------- 1 | // Empty strings are falsey 2 | let errorMessages = ''; 3 | 4 | // result is 'Saved OK' 5 | let result = errorMessages || 'Saved OK'; 6 | 7 | 8 | // Filled strings are truthy 9 | errorMessages = 'Error Detected'; 10 | 11 | // result is 'Error Detected' 12 | result = errorMessages || 'Saved OK'; 13 | 14 | 15 | let undefinedLogger; 16 | 17 | // if the logger isn't initialized, substitute it for the result of the right-hand expression 18 | const logger = undefinedLogger || { log: function (msg: string) { alert(msg); } }; 19 | 20 | // alerts 'Message' 21 | logger.log('Message'); -------------------------------------------------------------------------------- /CH01/Listing-1-038.js: -------------------------------------------------------------------------------- 1 | var caravan; 2 | if (caravan && caravan.rooms > 5) { 3 | //... 4 | } 5 | -------------------------------------------------------------------------------- /CH01/Listing-1-038.ts: -------------------------------------------------------------------------------- 1 | interface Caravan { 2 | rooms: number; 3 | } 4 | 5 | let caravan: Caravan; 6 | 7 | if (caravan && caravan.rooms > 5) { 8 | //... 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-039.js: -------------------------------------------------------------------------------- 1 | var isValid = true; 2 | var message; 3 | // Long-hand equivalent 4 | if (isValid) { 5 | message = 'Okay'; 6 | } 7 | else { 8 | message = 'Failed'; 9 | } 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-039.ts: -------------------------------------------------------------------------------- 1 | const isValid = true; 2 | let message: string; 3 | 4 | // Long-hand equivalent 5 | if (isValid) { 6 | message = 'Okay'; 7 | } else { 8 | message = 'Failed'; 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-040.js: -------------------------------------------------------------------------------- 1 | { 2 | var isValid_1 = true; 3 | // Conditional operator 4 | var message_1 = isValid_1 ? 'Okay' : 'Failed'; 5 | } 6 | -------------------------------------------------------------------------------- /CH01/Listing-1-040.ts: -------------------------------------------------------------------------------- 1 | { 2 | const isValid = true; 3 | 4 | // Conditional operator 5 | const message = isValid ? 'Okay' : 'Failed'; 6 | } -------------------------------------------------------------------------------- /CH01/Listing-1-041.js: -------------------------------------------------------------------------------- 1 | { 2 | var triangles = [1, 3, 6, 10, 15, 21]; 3 | // Destructuring 4 | var first = triangles[0], second = triangles[1]; 5 | // 1 6 | console.log(first); 7 | // 3 8 | console.log(second); 9 | } 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-041.ts: -------------------------------------------------------------------------------- 1 | { 2 | const triangles = [1, 3, 6, 10, 15, 21]; 3 | 4 | // Destructuring 5 | const [first, second] = triangles; 6 | 7 | // 1 8 | console.log(first); 9 | 10 | // 3 11 | console.log(second); 12 | } -------------------------------------------------------------------------------- /CH01/Listing-1-042.js: -------------------------------------------------------------------------------- 1 | { 2 | var triangles = [1, 3, 6, 10, 15, 21]; 3 | // Destructuring with a rest argument 4 | var first = triangles[0], second = triangles[1], remaining = triangles.slice(2); 5 | // 1 6 | console.log(first); 7 | // 3 8 | console.log(second); 9 | // [6, 10, 15, 21] 10 | console.log(remaining); 11 | } 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-042.ts: -------------------------------------------------------------------------------- 1 | { 2 | const triangles = [1, 3, 6, 10, 15, 21]; 3 | 4 | // Destructuring with a rest argument 5 | const [first, second, ...remaining] = triangles; 6 | 7 | // 1 8 | console.log(first); 9 | 10 | // 3 11 | console.log(second); 12 | 13 | // [6, 10, 15, 21] 14 | console.log(remaining); 15 | } -------------------------------------------------------------------------------- /CH01/Listing-1-043.js: -------------------------------------------------------------------------------- 1 | { 2 | var triangles = [1, 3, 6, 10, 15, 21]; 3 | // Skipping third item 4 | var first = triangles[0], second = triangles[1], fourth = triangles[3]; 5 | // 1 6 | console.log(first); 7 | // 3 8 | console.log(second); 9 | // [10] 10 | console.log(fourth); 11 | } 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-043.ts: -------------------------------------------------------------------------------- 1 | { 2 | const triangles = [1, 3, 6, 10, 15, 21]; 3 | 4 | // Skipping third item 5 | const [first, second, , fourth] = triangles; 6 | 7 | // 1 8 | console.log(first); 9 | 10 | // 3 11 | console.log(second); 12 | 13 | // [10] 14 | console.log(fourth); 15 | } -------------------------------------------------------------------------------- /CH01/Listing-1-044.js: -------------------------------------------------------------------------------- 1 | { 2 | var a = 3; 3 | var b = 5; 4 | // Swapping 5 | _a = [b, a], a = _a[0], b = _a[1]; 6 | // 5 7 | console.log(a); 8 | // 3 9 | console.log(b); 10 | } 11 | var _a; 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-044.ts: -------------------------------------------------------------------------------- 1 | { 2 | let a = 3; 3 | 4 | let b = 5; 5 | 6 | // Swapping 7 | [a, b] = [b, a]; 8 | 9 | // 5 10 | console.log(a); 11 | 12 | // 3 13 | console.log(b); 14 | } -------------------------------------------------------------------------------- /CH01/Listing-1-045.js: -------------------------------------------------------------------------------- 1 | { 2 | var highSchool = { school: 'Central High', team: 'Centaurs' }; 3 | // Object destructuring 4 | var s = highSchool.school, t = highSchool.team; 5 | // 'Central High' 6 | console.log(s); 7 | // 'Centaurs' 8 | console.log(t); 9 | } 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-045.ts: -------------------------------------------------------------------------------- 1 | { 2 | const highSchool = { school: 'Central High', team: 'Centaurs' }; 3 | 4 | // Object destructuring 5 | const { school: s, team: t } = highSchool; 6 | 7 | // 'Central High' 8 | console.log(s); 9 | 10 | // 'Centaurs' 11 | console.log(t); 12 | } -------------------------------------------------------------------------------- /CH01/Listing-1-046.js: -------------------------------------------------------------------------------- 1 | { 2 | var highSchool = { school: 'Central High', team: 'Centaurs' }; 3 | // Auto-unpacking 4 | var school = highSchool.school, team = highSchool.team; 5 | // 'Central High' 6 | console.log(school); 7 | // 'Centaurs' 8 | console.log(team); 9 | } 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-046.ts: -------------------------------------------------------------------------------- 1 | { 2 | const highSchool = { school: 'Central High', team: 'Centaurs' }; 3 | 4 | // Auto-unpacking 5 | const { school, team } = highSchool; 6 | 7 | // 'Central High' 8 | console.log(school); 9 | 10 | // 'Centaurs' 11 | console.log(team); 12 | } -------------------------------------------------------------------------------- /CH01/Listing-1-047.js: -------------------------------------------------------------------------------- 1 | var __rest = (this && this.__rest) || function (s, e) { 2 | var t = {}; 3 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 4 | t[p] = s[p]; 5 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 6 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) 7 | t[p[i]] = s[p[i]]; 8 | return t; 9 | }; 10 | { 11 | var pets = { cat: 'Pickle', dog: 'Berkeley', hamster: 'Hammy' }; 12 | // Object destructuring 13 | var dog = pets.dog, others = __rest(pets, ["dog"]); 14 | // 'Berkeley' 15 | console.log(dog); 16 | // Object { cat: 'Pickle', hamster: 'Hammy'} 17 | console.log(others); 18 | } 19 | -------------------------------------------------------------------------------- /CH01/Listing-1-047.ts: -------------------------------------------------------------------------------- 1 | { 2 | const pets = { cat: 'Pickle', dog: 'Berkeley', hamster: 'Hammy' } 3 | 4 | // Object destructuring 5 | const { dog, ...others } = pets; 6 | 7 | // 'Berkeley' 8 | console.log(dog); 9 | 10 | // Object { cat: 'Pickle', hamster: 'Hammy'} 11 | console.log(others); 12 | } -------------------------------------------------------------------------------- /CH01/Listing-1-048.js: -------------------------------------------------------------------------------- 1 | { 2 | var triangles = [1, 3, 6]; 3 | // Destructuring past available values 4 | var first = triangles[0], second = triangles[1], third = triangles[2], fourth = triangles[3]; 5 | // undefined 6 | console.log(fourth); 7 | } 8 | -------------------------------------------------------------------------------- /CH01/Listing-1-048.ts: -------------------------------------------------------------------------------- 1 | { 2 | const triangles = [1, 3, 6]; 3 | 4 | // Destructuring past available values 5 | const [first, second, third, fourth] = triangles; 6 | 7 | // undefined 8 | console.log(fourth); 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-049.js: -------------------------------------------------------------------------------- 1 | { 2 | var triangles = [1, 3, 6]; 3 | // Destructuring past available values 4 | var first = triangles[0], second = triangles[1], _a = triangles[2], third = _a === void 0 ? -1 : _a, _b = triangles[3], fourth = _b === void 0 ? -1 : _b; 5 | // 6 6 | console.log(third); 7 | // -1 8 | console.log(fourth); 9 | } 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-049.ts: -------------------------------------------------------------------------------- 1 | { 2 | const triangles = [1, 3, 6]; 3 | 4 | // Destructuring past available values 5 | const [first, second, third = -1, fourth = -1] = triangles; 6 | 7 | // 6 8 | console.log(third); 9 | 10 | // -1 11 | console.log(fourth); 12 | } -------------------------------------------------------------------------------- /CH01/Listing-1-050.js: -------------------------------------------------------------------------------- 1 | { 2 | // Returning a tuple 3 | function getThreeLandmarks() { 4 | return ['Golden Gate Bridge', 'Palace of Westminster', 'Colosseum ']; 5 | } 6 | // Destructuring the tuple into named variables 7 | var _a = getThreeLandmarks(), sanFrancisco = _a[0], london = _a[1], rome = _a[2]; 8 | } 9 | -------------------------------------------------------------------------------- /CH01/Listing-1-050.ts: -------------------------------------------------------------------------------- 1 | { 2 | // Returning a tuple 3 | function getThreeLandmarks(): [string, string, string] { 4 | return ['Golden Gate Bridge', 'Palace of Westminster', 'Colosseum ']; 5 | } 6 | 7 | // Destructuring the tuple into named variables 8 | const [sanFrancisco, london, rome] = getThreeLandmarks(); 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-051.js: -------------------------------------------------------------------------------- 1 | { 2 | var squares = [1, 4, 9, 16, 25]; 3 | var powers = [2, 4, 8, 16, 32]; 4 | // Array spreading 5 | var squaresAndPowers = squares.concat(powers); 6 | // [1, 4, 9, 16, 25, 2, 4, 8, 16, 32] 7 | console.log(squaresAndPowers); 8 | } 9 | -------------------------------------------------------------------------------- /CH01/Listing-1-051.ts: -------------------------------------------------------------------------------- 1 | { 2 | const squares = [1, 4, 9, 16, 25]; 3 | const powers = [2, 4, 8, 16, 32]; 4 | 5 | // Array spreading 6 | const squaresAndPowers = [...squares, ...powers]; 7 | 8 | // [1, 4, 9, 16, 25, 2, 4, 8, 16, 32] 9 | console.log(squaresAndPowers); 10 | } -------------------------------------------------------------------------------- /CH01/Listing-1-052.js: -------------------------------------------------------------------------------- 1 | var __assign = (this && this.__assign) || Object.assign || function(t) { 2 | for (var s, i = 1, n = arguments.length; i < n; i++) { 3 | s = arguments[i]; 4 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) 5 | t[p] = s[p]; 6 | } 7 | return t; 8 | }; 9 | { 10 | var emergencyService = { 11 | police: 'Chase', 12 | fire: 'Marshall', 13 | }; 14 | var utilityService = { 15 | recycling: 'Rocky', 16 | construction: 'Rubble' 17 | }; 18 | // Object spreading 19 | var patrol = __assign({}, emergencyService, utilityService); 20 | // { police: 'Chase', fire: 'Marshall', recycling: 'Rocky', construction: 'Rubble' } 21 | console.log(patrol); 22 | } 23 | -------------------------------------------------------------------------------- /CH01/Listing-1-052.ts: -------------------------------------------------------------------------------- 1 | { 2 | const emergencyService = { 3 | police: 'Chase', 4 | fire: 'Marshall', 5 | }; 6 | 7 | const utilityService = { 8 | recycling: 'Rocky', 9 | construction: 'Rubble' 10 | }; 11 | 12 | // Object spreading 13 | const patrol = { ...emergencyService, ...utilityService }; 14 | 15 | // { police: 'Chase', fire: 'Marshall', recycling: 'Rocky', construction: 'Rubble' } 16 | console.log(patrol); 17 | } -------------------------------------------------------------------------------- /CH01/Listing-1-053.js: -------------------------------------------------------------------------------- 1 | var Listing_1_50; 2 | (function (Listing_1_50) { 3 | function concatenate(items, separator, beginAt, endAt) { 4 | if (separator === void 0) { separator = ','; } 5 | if (beginAt === void 0) { beginAt = 0; } 6 | if (endAt === void 0) { endAt = items.length; } 7 | var result = ''; 8 | for (var i = beginAt; i < endAt; i++) { 9 | result += items[i]; 10 | if (i < (endAt - 1)) { 11 | result += separator; 12 | } 13 | } 14 | return result; 15 | } 16 | var items = ['A', 'B', 'C']; 17 | // 'A,B,C' 18 | var result = concatenate(items); 19 | // 'B-C' 20 | var partialResult = concatenate(items, '-', 1); 21 | })(Listing_1_50 || (Listing_1_50 = {})); 22 | -------------------------------------------------------------------------------- /CH01/Listing-1-053.ts: -------------------------------------------------------------------------------- 1 | { 2 | function add(a: number, b: number, c: number) { 3 | return a + b + c; 4 | } 5 | 6 | const hexagons = [1, 6, 15]; 7 | 8 | // Spread operator in function call 9 | const result = add(...hexagons); 10 | 11 | // 22 12 | console.log(result); 13 | } -------------------------------------------------------------------------------- /CH01/Listing-1-054.js: -------------------------------------------------------------------------------- 1 | var Listing_1_54; 2 | (function (Listing_1_54) { 3 | function getAverage(a, b, c) { 4 | var total = a + b + c; 5 | var average = total / 3; 6 | return 'The average is ' + average; 7 | } 8 | var result = getAverage(4, 3, 8); // 'The average is 5' 9 | })(Listing_1_54 || (Listing_1_54 = {})); 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-054.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_54 { 2 | function getAverage(a: number, b: number, c: number): string { 3 | const total = a + b + c; 4 | const average = total / 3; 5 | return 'The average is ' + average; 6 | } 7 | 8 | const result = getAverage(4, 3, 8); // 'The average is 5' 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-055.js: -------------------------------------------------------------------------------- 1 | var Listing_1_55; 2 | (function (Listing_1_55) { 3 | function getAverage(a, b, c) { 4 | var total = a; 5 | var count = 1; 6 | total += b; 7 | count++; 8 | if (typeof c !== 'undefined') { 9 | total += c; 10 | count++; 11 | } 12 | var average = total / count; 13 | return 'The average is ' + average; 14 | } 15 | // 'The average is 5' 16 | var result = getAverage(4, 6); 17 | })(Listing_1_55 || (Listing_1_55 = {})); 18 | -------------------------------------------------------------------------------- /CH01/Listing-1-055.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_55 { 2 | function getAverage(a: number, b: number, c?: number): string { 3 | let total = a; 4 | let count = 1; 5 | 6 | total += b; 7 | count++; 8 | 9 | if (typeof c !== 'undefined') { 10 | total += c; 11 | count++; 12 | } 13 | 14 | const average = total / count; 15 | return 'The average is ' + average; 16 | } 17 | 18 | // 'The average is 5' 19 | const result = getAverage(4, 6); 20 | } -------------------------------------------------------------------------------- /CH01/Listing-1-056.js: -------------------------------------------------------------------------------- 1 | var Listing_1_56; 2 | (function (Listing_1_56) { 3 | function concatenate(items, separator, beginAt, endAt) { 4 | if (separator === void 0) { separator = ','; } 5 | if (beginAt === void 0) { beginAt = 0; } 6 | if (endAt === void 0) { endAt = items.length; } 7 | var result = ''; 8 | for (var i = beginAt; i < endAt; i++) { 9 | result += items[i]; 10 | if (i < (endAt - 1)) { 11 | result += separator; 12 | } 13 | } 14 | return result; 15 | } 16 | var items = ['A', 'B', 'C']; 17 | // 'A,B,C' 18 | var result = concatenate(items); 19 | // 'B-C' 20 | var partialResult = concatenate(items, '-', 1); 21 | })(Listing_1_56 || (Listing_1_56 = {})); 22 | -------------------------------------------------------------------------------- /CH01/Listing-1-056.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_56 { 2 | function concatenate(items: string[], separator = ',', beginAt = 0, endAt = items.length) { 3 | let result = ''; 4 | 5 | for (let i = beginAt; i < endAt; i++) { 6 | result += items[i]; 7 | if (i < (endAt - 1)) { 8 | result += separator; 9 | } 10 | } 11 | 12 | return result; 13 | } 14 | 15 | const items = ['A', 'B', 'C']; 16 | 17 | // 'A,B,C' 18 | const result = concatenate(items); 19 | 20 | // 'B-C' 21 | const partialResult = concatenate(items, '-', 1); 22 | } 23 | -------------------------------------------------------------------------------- /CH01/Listing-1-057.js: -------------------------------------------------------------------------------- 1 | var Listing_1_57; 2 | (function (Listing_1_57) { 3 | function getAverage() { 4 | var a = []; 5 | for (var _i = 0; _i < arguments.length; _i++) { 6 | a[_i] = arguments[_i]; 7 | } 8 | var total = 0; 9 | var count = 0; 10 | for (var i = 0; i < a.length; i++) { 11 | total += a[i]; 12 | count++; 13 | } 14 | var average = total / count; 15 | return 'The average is ' + average; 16 | } 17 | // 'The average is 6' 18 | var result = getAverage(2, 4, 6, 8, 10); 19 | })(Listing_1_57 || (Listing_1_57 = {})); 20 | -------------------------------------------------------------------------------- /CH01/Listing-1-057.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_57 { 2 | function getAverage(...a: number[]): string { 3 | let total = 0; 4 | let count = 0; 5 | 6 | for (let i = 0; i < a.length; i++) { 7 | total += a[i]; 8 | count++; 9 | } 10 | 11 | const average = total / count; 12 | return 'The average is ' + average; 13 | } 14 | 15 | // 'The average is 6' 16 | const result = getAverage(2, 4, 6, 8, 10); 17 | } -------------------------------------------------------------------------------- /CH01/Listing-1-058.js: -------------------------------------------------------------------------------- 1 | var Listing_1_58; 2 | (function (Listing_1_58) { 3 | // implementation signature 4 | function getAverage(a, b, c) { 5 | var total = parseInt(a, 10) + parseInt(b, 10) + parseInt(c, 10); 6 | var average = total / 3; 7 | return 'The average is ' + average; 8 | } 9 | // The average is 5 10 | var result = getAverage(4, 3, 8); 11 | })(Listing_1_58 || (Listing_1_58 = {})); 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-058.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_58 { 2 | function getAverage(a: string, b: string, c: string): string; 3 | function getAverage(a: number, b: number, c: number): string; 4 | // implementation signature 5 | function getAverage(a: any, b: any, c: any): string { 6 | const total = parseInt(a, 10) + parseInt(b, 10) + parseInt(c, 10); 7 | const average = total / 3; 8 | return 'The average is ' + average; 9 | } 10 | 11 | // The average is 5 12 | const result = getAverage(4, 3, 8); 13 | } -------------------------------------------------------------------------------- /CH01/Listing-1-059.ts: -------------------------------------------------------------------------------- 1 | class Handler { 2 | // ... 3 | } 4 | 5 | class RandomHandler extends Handler { 6 | // ... 7 | } 8 | 9 | class ReversedHandler extends Handler { 10 | // ... 11 | } 12 | 13 | class HandlerFactory { 14 | getHandler(type: 'Random'): RandomHandler; 15 | getHandler(type: 'Reversed'): ReversedHandler; 16 | getHandler(type: string): Handler; // non-specialized signature 17 | getHandler(type: string): Handler { // implementation signature 18 | switch (type) { 19 | case 'Random': 20 | return new RandomHandler(); 21 | case 'Reversed': 22 | return new ReversedHandler(); 23 | default: 24 | return new Handler(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /CH01/Listing-1-060.js: -------------------------------------------------------------------------------- 1 | var Example = /** @class */ (function () { 2 | function Example() { 3 | } 4 | Example.prototype.getElementsByTagName = function (name) { 5 | return document.getElementsByTagName(name); 6 | }; 7 | return Example; 8 | }()); 9 | -------------------------------------------------------------------------------- /CH01/Listing-1-060.ts: -------------------------------------------------------------------------------- 1 | class Example { 2 | // This example does not list all variations... 3 | getElementsByTagName(name: "a"): NodeListOf; 4 | getElementsByTagName(name: "blockquote"): NodeListOf; 5 | getElementsByTagName(name: "body"): NodeListOf; 6 | getElementsByTagName(name: "button"): NodeListOf; 7 | getElementsByTagName(name: "form"): NodeListOf; 8 | getElementsByTagName(name: "h1"): NodeListOf; 9 | getElementsByTagName(name: string): NodeList; // Non-specialized signature 10 | getElementsByTagName(name: string): NodeList { // implementation signature 11 | return document.getElementsByTagName(name); 12 | } 13 | } -------------------------------------------------------------------------------- /CH01/Listing-1-061.js: -------------------------------------------------------------------------------- 1 | { 2 | var shortAddNumbers = function (a, b) { return a + b; }; 3 | var mediumAddNumbers = function (a, b) { 4 | return a + b; 5 | }; 6 | var longAddNumbers = function (a, b) { 7 | return a + b; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-061.ts: -------------------------------------------------------------------------------- 1 | { 2 | const shortAddNumbers = (a: number, b: number) => a + b; 3 | 4 | const mediumAddNumbers = (a: number, b: number) => { 5 | return a + b; 6 | } 7 | 8 | const longAddNumbers = function (a: number, b: number) { 9 | return a + b; 10 | } 11 | } -------------------------------------------------------------------------------- /CH01/Listing-1-062.js: -------------------------------------------------------------------------------- 1 | { 2 | var makeName = function (f, l) { return ({ first: f, last: l }); }; 3 | } 4 | -------------------------------------------------------------------------------- /CH01/Listing-1-062.ts: -------------------------------------------------------------------------------- 1 | { 2 | const makeName = (f: string, l: string) => ({ first: f, last: l }); 3 | } -------------------------------------------------------------------------------- /CH01/Listing-1-063.js: -------------------------------------------------------------------------------- 1 | var scopeLosingExample = { 2 | text: "Property from lexical scope", 3 | run: function () { 4 | setTimeout(function () { 5 | alert(this.text); 6 | }, 1000); 7 | } 8 | }; 9 | // alerts undefined 10 | scopeLosingExample.run(); 11 | var scopePreservingExample = { 12 | text: "Property from lexical scope", 13 | run: function () { 14 | var _this = this; 15 | setTimeout(function () { 16 | alert(_this.text); 17 | }, 1000); 18 | } 19 | }; 20 | // alerts "Property from lexical scope" 21 | scopePreservingExample.run(); 22 | -------------------------------------------------------------------------------- /CH01/Listing-1-063.ts: -------------------------------------------------------------------------------- 1 | const scopeLosingExample = { 2 | text: "Property from lexical scope", 3 | run: function () { 4 | setTimeout(function () { 5 | alert(this.text); 6 | }, 1000); 7 | } 8 | }; 9 | 10 | // alerts undefined 11 | scopeLosingExample.run(); 12 | 13 | const scopePreservingExample = { 14 | text: "Property from lexical scope", 15 | run: function () { 16 | setTimeout(() => { 17 | alert(this.text); 18 | }, 1000); 19 | } 20 | }; 21 | 22 | // alerts "Property from lexical scope" 23 | scopePreservingExample.run(); -------------------------------------------------------------------------------- /CH01/Listing-1-064.js: -------------------------------------------------------------------------------- 1 | var Currying; 2 | (function (Currying) { 3 | // Currying 4 | var multiply = function (a) { return function (b) { return a * b; }; }; 5 | // Pass both arguments in sequence: 30 6 | var numA = multiply(5)(6); 7 | // Pass just the first argument and re-use 8 | var orderOfMagnitude = multiply(10); 9 | // 10 10 | var deca = orderOfMagnitude(1); 11 | // 100 12 | var hecta = orderOfMagnitude(deca); 13 | // 1,000 14 | var kilo = orderOfMagnitude(hecta); 15 | })(Currying || (Currying = {})); 16 | -------------------------------------------------------------------------------- /CH01/Listing-1-064.ts: -------------------------------------------------------------------------------- 1 | namespace Currying { 2 | // Currying 3 | const multiply = (a: number) => (b: number) => a * b; 4 | 5 | // Pass both arguments in sequence: 30 6 | const numA = multiply(5)(6); 7 | 8 | // Pass just the first argument and re-use 9 | const orderOfMagnitude = multiply(10); 10 | 11 | // 10 12 | const deca = orderOfMagnitude(1); 13 | 14 | // 100 15 | const hecta = orderOfMagnitude(deca); 16 | 17 | // 1,000 18 | const kilo = orderOfMagnitude(hecta); 19 | } -------------------------------------------------------------------------------- /CH01/Listing-1-065.js: -------------------------------------------------------------------------------- 1 | var FlexiCurrying; 2 | (function (FlexiCurrying) { 3 | function multiply(a, b) { 4 | if (b === void 0) { b = null; } 5 | if (b === null) { 6 | return function (b) { return a * b; }; 7 | } 8 | return a * b; 9 | } 10 | // Pass both arguments "normally": 30 11 | var numA = multiply(5, 6); 12 | // Pass just the first argument and re-use 13 | var orderOfMagnitude = multiply(10); 14 | // 10 15 | var deca = orderOfMagnitude(1); 16 | // 100 17 | var hecta = orderOfMagnitude(deca); 18 | // 1,000 19 | var kilo = orderOfMagnitude(hecta); 20 | })(FlexiCurrying || (FlexiCurrying = {})); 21 | -------------------------------------------------------------------------------- /CH01/Listing-1-065.ts: -------------------------------------------------------------------------------- 1 | namespace FlexiCurrying { 2 | function multiply(a: number): (b: number) => number; 3 | function multiply(a: number, b: number): number; 4 | function multiply(a: number, b: number = null) { 5 | if (b === null) { 6 | return (b: number) => a * b; 7 | } 8 | 9 | return a * b; 10 | } 11 | 12 | // Pass both arguments "normally": 30 13 | const numA = multiply(5, 6); 14 | 15 | // Pass just the first argument and re-use 16 | const orderOfMagnitude = multiply(10); 17 | 18 | // 10 19 | const deca = orderOfMagnitude(1); 20 | 21 | // 100 22 | const hecta = orderOfMagnitude(deca); 23 | 24 | // 1,000 25 | const kilo = orderOfMagnitude(hecta); 26 | } -------------------------------------------------------------------------------- /CH01/Listing-1-066.js: -------------------------------------------------------------------------------- 1 | var log = function (source) { return function (message) { return console.log(source, message); }; }; 2 | var customLog = log('Custom Log:'); 3 | // Custom Log: Message One 4 | customLog('Message One'); 5 | // Custom Log: Message Two 6 | customLog('Message Two'); 7 | -------------------------------------------------------------------------------- /CH01/Listing-1-066.ts: -------------------------------------------------------------------------------- 1 | const log = (source: string) => (message: string) => console.log(source, message); 2 | 3 | const customLog = log('Custom Log:'); 4 | 5 | // Custom Log: Message One 6 | customLog('Message One'); 7 | 8 | // Custom Log: Message Two 9 | customLog('Message Two'); -------------------------------------------------------------------------------- /CH01/Listing-1-067.js: -------------------------------------------------------------------------------- 1 | var z; 2 | -------------------------------------------------------------------------------- /CH01/Listing-1-067.ts: -------------------------------------------------------------------------------- 1 | interface Point { 2 | // Properties 3 | x: number; 4 | y: number; 5 | } 6 | 7 | interface Passenger { 8 | // Properties 9 | name: string; 10 | } 11 | 12 | interface Vehicle { 13 | // Constructor 14 | new(): Vehicle; 15 | 16 | // Properties 17 | currentLocation: Point; 18 | 19 | // Methods 20 | travelTo(point: Point): void; 21 | addPassenger(passenger: Passenger): void; 22 | removePassenger(passenger: Passenger): void; 23 | } 24 | 25 | var z: NodeListOf; -------------------------------------------------------------------------------- /CH01/Listing-1-068.ts: -------------------------------------------------------------------------------- 1 | interface NodeList { 2 | readonly length: number; 3 | item(index: number): Node; 4 | [index: number]: Node; 5 | } 6 | -------------------------------------------------------------------------------- /CH01/Listing-1-069.js: -------------------------------------------------------------------------------- 1 | var nodeList = document.getElementsByTagName('div'); 2 | nodeList.onclick = function (event) { 3 | alert('Clicked'); 4 | }; 5 | -------------------------------------------------------------------------------- /CH01/Listing-1-069.ts: -------------------------------------------------------------------------------- 1 | interface NodeList { 2 | onclick: (event: MouseEvent) => any; 3 | } 4 | 5 | const nodeList = document.getElementsByTagName('div'); 6 | 7 | nodeList.onclick = function (event: MouseEvent) { 8 | alert('Clicked'); 9 | }; 10 | -------------------------------------------------------------------------------- /CH01/Listing-1-070.js: -------------------------------------------------------------------------------- 1 | // Implementation 2 | var prepareDocument = function () { 3 | var doc = function (selector) { 4 | return document.getElementById(selector); 5 | }; 6 | doc.notify = function (message) { 7 | alert(message); 8 | }; 9 | return doc; 10 | }; 11 | var $ = prepareDocument(); 12 | // Call $ as a function 13 | var elem = $('myId'); 14 | // Use $ as an object 15 | $.notify(elem.id); 16 | -------------------------------------------------------------------------------- /CH01/Listing-1-070.ts: -------------------------------------------------------------------------------- 1 | // Hybrid type 2 | interface SimpleDocument { 3 | (selector: string): HTMLElement; 4 | notify(message: string): void; 5 | } 6 | 7 | // Implementation 8 | const prepareDocument = function (): SimpleDocument { 9 | let doc = function (selector: string) { 10 | return document.getElementById(selector); 11 | }; 12 | 13 | doc.notify = function (message: string) { 14 | alert(message); 15 | } 16 | 17 | return doc; 18 | } 19 | 20 | const $ = prepareDocument(); 21 | 22 | // Call $ as a function 23 | const elem = $('myId'); 24 | 25 | // Use $ as an object 26 | $.notify(elem.id); -------------------------------------------------------------------------------- /CH01/Listing-1-071.ts: -------------------------------------------------------------------------------- 1 | class Song { 2 | constructor(private artist: string, private title: string) { 3 | 4 | } 5 | 6 | play() { 7 | console.log('Playing ' + this.title + ' by ' + this.artist); 8 | } 9 | } 10 | 11 | class Jukebox { 12 | constructor(private songs: Song[]) { 13 | } 14 | 15 | play() { 16 | const song = this.getRandomSong(); 17 | song.play(); 18 | } 19 | 20 | private getRandomSong() { 21 | const songCount = this.songs.length; 22 | const songIndex = Math.floor(Math.random() * songCount); 23 | 24 | return this.songs[songIndex]; 25 | } 26 | } 27 | 28 | const songs = [ 29 | new Song('Bushbaby', 'Megaphone'), 30 | new Song('Delays', 'One More Lie In'), 31 | new Song('Goober Gun', 'Stereo'), 32 | new Song('Sohnee', 'Shatter'), 33 | new Song('Get Amped', 'Celebrity') 34 | ]; 35 | 36 | const jukebox = new Jukebox(songs); 37 | 38 | jukebox.play(); -------------------------------------------------------------------------------- /CH01/Listing-1-072.js: -------------------------------------------------------------------------------- 1 | var Listing_1_72; 2 | (function (Listing_1_72) { 3 | var Song = /** @class */ (function () { 4 | function Song(artist, title) { 5 | // Don't do this! 6 | this.artist = artist; 7 | this.title = title; 8 | } 9 | Song.prototype.play = function () { 10 | console.log('Playing ' + this.title + ' by ' + this.artist); 11 | }; 12 | return Song; 13 | }()); 14 | })(Listing_1_72 || (Listing_1_72 = {})); 15 | -------------------------------------------------------------------------------- /CH01/Listing-1-072.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_72 { 2 | class Song { 3 | 4 | private artist: string; 5 | private title: string; 6 | 7 | constructor(artist: string, title: string) { 8 | // Don't do this! 9 | this.artist = artist; 10 | this.title = title; 11 | } 12 | 13 | play() { 14 | console.log('Playing ' + this.title + ' by ' + this.artist); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /CH01/Listing-1-073.js: -------------------------------------------------------------------------------- 1 | var Listing_1_66; 2 | (function (Listing_1_66) { 3 | var WarehouseLocation = (function () { 4 | function WarehouseLocation(aisle, slot) { 5 | this.aisle = aisle; 6 | this.slot = slot; 7 | } 8 | Object.defineProperty(WarehouseLocation.prototype, "stockItem", { 9 | get: function () { 10 | return this._stockItem; 11 | }, 12 | set: function (item) { 13 | this._stockItem = item; 14 | }, 15 | enumerable: true, 16 | configurable: true 17 | }); 18 | return WarehouseLocation; 19 | }()); 20 | var figure = { asin: 'B001TEQ2PI', description: 'Figure' }; 21 | var warehouseSlot = new WarehouseLocation(15, 'A6'); 22 | warehouseSlot.stockItem = figure; 23 | })(Listing_1_66 || (Listing_1_66 = {})); 24 | -------------------------------------------------------------------------------- /CH01/Listing-1-073.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_73 { 2 | class Playlist { 3 | 4 | private songs: Song[] = []; 5 | 6 | static readonly maxSongCount = 30; 7 | 8 | constructor(public name: string) { 9 | } 10 | 11 | addSong(song: Song) { 12 | if (this.songs.length >= Playlist.maxSongCount) { 13 | throw new Error('Playlist is full'); 14 | } 15 | 16 | this.songs.push(song); 17 | } 18 | } 19 | 20 | // Creating a new instance 21 | const playlist = new Playlist('My Playlist'); 22 | 23 | // Accessing a public instance property 24 | const name = playlist.name; 25 | 26 | // Calling a public instance method 27 | playlist.addSong(new Song('Therapy?', 'Crooked Timber')); 28 | 29 | // Accessing a public static property 30 | const maxSongs = Playlist.maxSongCount; 31 | 32 | // Error: Cannot assign to a readonly property 33 | Playlist.maxSongCount = 20; 34 | } -------------------------------------------------------------------------------- /CH01/Listing-1-074.js: -------------------------------------------------------------------------------- 1 | var Listing_1_74; 2 | (function (Listing_1_74) { 3 | var WarehouseLocation = /** @class */ (function () { 4 | function WarehouseLocation(aisle, slot) { 5 | this.aisle = aisle; 6 | this.slot = slot; 7 | } 8 | Object.defineProperty(WarehouseLocation.prototype, "stockItem", { 9 | get: function () { 10 | return this._stockItem; 11 | }, 12 | set: function (item) { 13 | this._stockItem = item; 14 | }, 15 | enumerable: true, 16 | configurable: true 17 | }); 18 | return WarehouseLocation; 19 | }()); 20 | var figure = { asin: 'B001TEQ2PI', description: 'Figure' }; 21 | var warehouseSlot = new WarehouseLocation(15, 'A6'); 22 | warehouseSlot.stockItem = figure; 23 | })(Listing_1_74 || (Listing_1_74 = {})); 24 | -------------------------------------------------------------------------------- /CH01/Listing-1-074.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_74 { 2 | interface StockItem { 3 | description: string; 4 | asin: string; 5 | } 6 | 7 | class WarehouseLocation { 8 | private _stockItem: StockItem; 9 | 10 | constructor(public aisle: number, public slot: string) { 11 | 12 | } 13 | 14 | get stockItem() { 15 | return this._stockItem; 16 | } 17 | 18 | set stockItem(item: StockItem) { 19 | this._stockItem = item; 20 | } 21 | } 22 | 23 | const figure = { asin: 'B001TEQ2PI', description: 'Figure' }; 24 | 25 | const warehouseSlot = new WarehouseLocation(15, 'A6'); 26 | 27 | warehouseSlot.stockItem = figure; 28 | } -------------------------------------------------------------------------------- /CH01/Listing-1-076.js: -------------------------------------------------------------------------------- 1 | var ClickCounter = (function () { 2 | function ClickCounter() { 3 | this.count = 0; 4 | } 5 | ClickCounter.prototype.registerClick = function () { 6 | this.count++; 7 | alert(this.count); 8 | }; 9 | return ClickCounter; 10 | }()); 11 | var clickCounter = new ClickCounter(); 12 | document.getElementById('target').onclick = clickCounter.registerClick; 13 | -------------------------------------------------------------------------------- /CH01/Listing-1-076.ts: -------------------------------------------------------------------------------- 1 | namespace Abstract { 2 | // Abstract class 3 | abstract class Logger { 4 | abstract notify(message: string): void; 5 | 6 | protected getMessage(message: string): string { 7 | return `Information: ${new Date().toUTCString()} ${message}`; 8 | } 9 | } 10 | 11 | class ConsoleLogger extends Logger { 12 | notify(message) { 13 | console.log(this.getMessage(message)); 14 | } 15 | } 16 | 17 | class InvasiveLogger extends Logger { 18 | notify(message) { 19 | alert(this.getMessage(message)); 20 | } 21 | } 22 | 23 | let logger: Logger; 24 | 25 | // Error. Cannot create an instance of an abstract class 26 | logger = new Logger(); 27 | 28 | // Create an instance of a sub-class 29 | logger = new InvasiveLogger(); 30 | 31 | logger.notify('Hello World'); 32 | } -------------------------------------------------------------------------------- /CH01/Listing-1-077.js: -------------------------------------------------------------------------------- 1 | var ClickCounter = /** @class */ (function () { 2 | function ClickCounter() { 3 | this.count = 0; 4 | } 5 | ClickCounter.prototype.registerClick = function () { 6 | this.count++; 7 | alert(this.count); 8 | }; 9 | return ClickCounter; 10 | }()); 11 | var clickCounter = new ClickCounter(); 12 | document.getElementById('target').onclick = clickCounter.registerClick; 13 | -------------------------------------------------------------------------------- /CH01/Listing-1-077.ts: -------------------------------------------------------------------------------- 1 | class ClickCounter { 2 | private count = 0; 3 | 4 | registerClick() { 5 | this.count++; 6 | alert(this.count); 7 | } 8 | } 9 | 10 | const clickCounter = new ClickCounter(); 11 | 12 | document.getElementById('target').onclick = clickCounter.registerClick; 13 | -------------------------------------------------------------------------------- /CH01/Listing-1-078.js: -------------------------------------------------------------------------------- 1 | var Listing_1_78; 2 | (function (Listing_1_78) { 3 | var ClickCounter = /** @class */ (function () { 4 | function ClickCounter() { 5 | var _this = this; 6 | this.count = 0; 7 | this.registerClick = function () { 8 | _this.count++; 9 | alert(_this.count); 10 | }; 11 | } 12 | return ClickCounter; 13 | }()); 14 | })(Listing_1_78 || (Listing_1_78 = {})); 15 | -------------------------------------------------------------------------------- /CH01/Listing-1-078.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_78 { 2 | class ClickCounter { 3 | private count = 0; 4 | 5 | registerClick = () => { 6 | this.count++; 7 | alert(this.count); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /CH01/Listing-1-079.js: -------------------------------------------------------------------------------- 1 | document.getElementById('target').onclick = function () { 2 | clickCounter.registerClick(); 3 | }; 4 | -------------------------------------------------------------------------------- /CH01/Listing-1-079.ts: -------------------------------------------------------------------------------- 1 | document.getElementById('target').onclick = function () { 2 | clickCounter.registerClick(); 3 | }; -------------------------------------------------------------------------------- /CH01/Listing-1-080.js: -------------------------------------------------------------------------------- 1 | var clickHandler = clickCounter.registerClick.bind(clickCounter); 2 | document.getElementById('target').onclick = clickHandler; 3 | -------------------------------------------------------------------------------- /CH01/Listing-1-080.ts: -------------------------------------------------------------------------------- 1 | const clickHandler = clickCounter.registerClick.bind(clickCounter); 2 | 3 | document.getElementById('target').onclick = clickHandler; -------------------------------------------------------------------------------- /CH01/Listing-1-081.js: -------------------------------------------------------------------------------- 1 | var Listing_1_81; 2 | (function (Listing_1_81) { 3 | var ClickCounter = /** @class */ (function () { 4 | function ClickCounter() { 5 | this.count = 0; 6 | } 7 | ClickCounter.prototype.registerClick = function (id) { 8 | this.count++; 9 | alert(this.count); 10 | }; 11 | return ClickCounter; 12 | }()); 13 | var clickCounter = new ClickCounter(); 14 | document.getElementById('target').onclick = function (e) { 15 | var target = e.target || e.srcElement; 16 | clickCounter.registerClick(target.id); 17 | }; 18 | })(Listing_1_81 || (Listing_1_81 = {})); 19 | -------------------------------------------------------------------------------- /CH01/Listing-1-081.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_81 { 2 | class ClickCounter { 3 | private count = 0; 4 | 5 | registerClick(id: string) { 6 | this.count++; 7 | alert(this.count); 8 | } 9 | } 10 | 11 | const clickCounter = new ClickCounter(); 12 | 13 | document.getElementById('target').onclick = (e) => { 14 | const target = e.target || e.srcElement; 15 | clickCounter.registerClick(target.id); 16 | }; 17 | } -------------------------------------------------------------------------------- /CH01/Listing-1-082.ts: -------------------------------------------------------------------------------- 1 | class Display { 2 | name: string = ''; 3 | } 4 | 5 | class Television extends Display { 6 | 7 | } 8 | 9 | class HiFi { 10 | 11 | } 12 | 13 | const display = new Display(); 14 | const television = new Television(); 15 | const hiFi = new HiFi(); 16 | 17 | let isDisplay; 18 | 19 | // true 20 | isDisplay = display instanceof Display; 21 | 22 | // true (inherits from Display) 23 | isDisplay = television instanceof Display; 24 | 25 | // false 26 | isDisplay = hiFi instanceof Display; 27 | -------------------------------------------------------------------------------- /CH01/Listing-1-083.js: -------------------------------------------------------------------------------- 1 | var hasName; 2 | // true 3 | hasName = 'name' in display; 4 | // true 5 | hasName = 'name' in television; 6 | // false 7 | hasName = 'name' in hiFi; 8 | -------------------------------------------------------------------------------- /CH01/Listing-1-083.ts: -------------------------------------------------------------------------------- 1 | let hasName; 2 | 3 | // true 4 | hasName = 'name' in display; 5 | 6 | // true 7 | hasName = 'name' in television; 8 | 9 | // false 10 | hasName = 'name' in hiFi; -------------------------------------------------------------------------------- /CH01/Listing-1-084.js: -------------------------------------------------------------------------------- 1 | var Listing_1_84; 2 | (function (Listing_1_84) { 3 | var Display = /** @class */ (function () { 4 | function Display() { 5 | } 6 | return Display; 7 | }()); 8 | var display = new Display(); 9 | // false 10 | var hasName = 'name' in display; 11 | })(Listing_1_84 || (Listing_1_84 = {})); 12 | -------------------------------------------------------------------------------- /CH01/Listing-1-084.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_1_84 { 2 | class Display { 3 | name: string; 4 | } 5 | 6 | const display = new Display(); 7 | 8 | // false 9 | const hasName = 'name' in display; 10 | } -------------------------------------------------------------------------------- /CH01/Listing-1-085.js: -------------------------------------------------------------------------------- 1 | function reverse(list) { 2 | var reversedList = []; 3 | for (var i = (list.length - 1); i >= 0; i--) { 4 | reversedList.push(list[i]); 5 | } 6 | return reversedList; 7 | } 8 | var letters = ['a', 'b', 'c', 'd']; 9 | // d, c, b, a 10 | var reversedLetters = reverse(letters); 11 | var numbers = [1, 2, 3, 4]; 12 | // 4, 3, 2, 1 13 | var reversedNumbers = reverse(numbers); 14 | -------------------------------------------------------------------------------- /CH01/Listing-1-085.ts: -------------------------------------------------------------------------------- 1 | const tv = new Television(); 2 | const radio = new HiFi(); 3 | 4 | // Television 5 | const tvType = tv.constructor.name; 6 | 7 | // HiFi 8 | const radioType = radio.constructor.name; -------------------------------------------------------------------------------- /CH01/Listing-1-086.js: -------------------------------------------------------------------------------- 1 | function reverse(list) { 2 | var reversedList = []; 3 | for (var i = (list.length - 1); i >= 0; i--) { 4 | reversedList.push(list[i]); 5 | } 6 | return reversedList; 7 | } 8 | var letters = ['a', 'b', 'c', 'd']; 9 | // d, c, b, a 10 | var reversedLetters = reverse(letters); 11 | var numbers = [1, 2, 3, 4]; 12 | // 4, 3, 2, 1 13 | var reversedNumbers = reverse(numbers); 14 | -------------------------------------------------------------------------------- /CH01/Listing-1-086.ts: -------------------------------------------------------------------------------- 1 | function reverse(list: T[]): T[] { 2 | const reversedList: T[] = []; 3 | 4 | for (let i = (list.length - 1); i >= 0; i--) { 5 | reversedList.push(list[i]); 6 | } 7 | 8 | return reversedList; 9 | } 10 | 11 | const letters = ['a', 'b', 'c', 'd']; 12 | 13 | // d, c, b, a 14 | const reversedLetters = reverse(letters); 15 | 16 | 17 | const numbers = [1, 2, 3, 4]; 18 | 19 | // 4, 3, 2, 1 20 | const reversedNumbers = reverse(numbers); -------------------------------------------------------------------------------- /CH01/Listing-1-087.ts: -------------------------------------------------------------------------------- 1 | class CustomerId { 2 | constructor(private customerIdValue: number) { 3 | } 4 | 5 | get value() { 6 | return this.customerIdValue; 7 | } 8 | } 9 | 10 | class Customer { 11 | constructor(public id: CustomerId, public name: string) { 12 | 13 | } 14 | } 15 | 16 | interface Repository { 17 | getById(id: TId): T; 18 | persist(model: T): TId; 19 | } 20 | 21 | class CustomerRepository implements Repository { 22 | constructor(private customers: Customer[]) { 23 | 24 | } 25 | 26 | getById(id: CustomerId) { 27 | return this.customers[id.value]; 28 | } 29 | 30 | persist(customer: Customer) { 31 | this.customers[customer.id.value] = customer; 32 | return customer.id; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CH01/Listing-1-088.js: -------------------------------------------------------------------------------- 1 | var Personalization = (function () { 2 | function Personalization() { 3 | } 4 | Personalization.greet = function (obj) { 5 | return 'Hello ' + obj.name; 6 | }; 7 | return Personalization; 8 | }()); 9 | -------------------------------------------------------------------------------- /CH01/Listing-1-088.ts: -------------------------------------------------------------------------------- 1 | class DomainId { 2 | constructor(private id: T) { 3 | 4 | } 5 | 6 | get value(): T { 7 | return this.id; 8 | } 9 | } 10 | 11 | class OrderId extends DomainId { 12 | constructor(private orderIdValue: number) { 13 | super(orderIdValue); 14 | } 15 | } 16 | 17 | class AccountId extends DomainId { 18 | constructor(private accountIdValue: string) { 19 | super(accountIdValue); 20 | } 21 | } 22 | 23 | // Examples of compatibility 24 | 25 | function onlyAcceptsOrderId(orderId: OrderId) { 26 | // ... 27 | } 28 | 29 | function acceptsAnyDomainId(id: DomainId) { 30 | // ... 31 | } 32 | 33 | const accountId = new AccountId('GUID-1'); 34 | const orderId = new OrderId(5); 35 | 36 | // Error: Argument of type 'AccountId' is not assignable to parameter of type 'OrderId' 37 | onlyAcceptsOrderId(accountId); 38 | 39 | // OK 40 | onlyAcceptsOrderId(orderId); 41 | 42 | // OK 43 | acceptsAnyDomainId(accountId); -------------------------------------------------------------------------------- /CH01/Listing-1-089.js: -------------------------------------------------------------------------------- 1 | var Personalization = /** @class */ (function () { 2 | function Personalization() { 3 | } 4 | Personalization.greet = function (obj) { 5 | return 'Hello ' + obj.name; 6 | }; 7 | return Personalization; 8 | }()); 9 | -------------------------------------------------------------------------------- /CH01/Listing-1-089.ts: -------------------------------------------------------------------------------- 1 | interface HasName { 2 | name: string; 3 | } 4 | 5 | class Personalization { 6 | static greet(obj: T) { 7 | return 'Hello ' + obj.name; 8 | } 9 | } -------------------------------------------------------------------------------- /CH01/Listing-1-19.js: -------------------------------------------------------------------------------- 1 | // The array is typed using the Monument interface 2 | var monuments = []; 3 | // Each item added to the array is checked for type compatibility 4 | monuments.push({ 5 | name: 'Statue of Liberty', 6 | heightInMeters: 46 7 | }); 8 | monuments.push({ 9 | name: 'Peter the Great', 10 | heightInMeters: 96 11 | }); 12 | monuments.push({ 13 | name: 'Angel of the North', 14 | heightInMeters: 20 15 | }); 16 | function compareMonumentHeights(a, b) { 17 | if (a.heightInMeters > b.heightInMeters) { 18 | return -1; 19 | } 20 | if (a.heightInMeters < b.heightInMeters) { 21 | return 1; 22 | } 23 | return 0; 24 | } 25 | // The array.sort method expects a comparer that accepts two Monuments 26 | var monumentsOrderedByHeight = monuments.sort(compareMonumentHeights); 27 | // Get the first element from the array, which is the tallest 28 | var tallestMonument = monumentsOrderedByHeight[0]; 29 | // Peter the Great 30 | console.log(tallestMonument.name); 31 | -------------------------------------------------------------------------------- /CH01/Listing-1-40.js: -------------------------------------------------------------------------------- 1 | { 2 | var triangles = [1, 3, 6]; 3 | var first = void 0, second = void 0, third = void 0, fourth = void 0; 4 | // Destructuring past available values 5 | first = triangles[0], second = triangles[1], _a = triangles[2], third = _a === void 0 ? -1 : _a, _b = triangles[3], fourth = _b === void 0 ? -1 : _b; 6 | // 6 7 | console.log(third); 8 | // -1 9 | console.log(fourth); 10 | } 11 | var _a, _b; 12 | -------------------------------------------------------------------------------- /CH01/obj/Debug/Chapter01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH01/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH01/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH01/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH02/.vs/Chapter02/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH02/.vs/Chapter02/v15/.suo -------------------------------------------------------------------------------- /CH02/.vs/Chapter02/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH02/.vs/Chapter02/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH02/Figure-0-0.js: -------------------------------------------------------------------------------- 1 | (function (factory) { 2 | if (typeof module === "object" && typeof module.exports === "object") { 3 | var v = factory(require, exports); 4 | if (v !== undefined) module.exports = v; 5 | } 6 | else if (typeof define === "function" && define.amd) { 7 | define(["require", "exports"], factory); 8 | } 9 | })(function (require, exports) { 10 | "use strict"; 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | }); 13 | -------------------------------------------------------------------------------- /CH02/Figure-2-001.ts: -------------------------------------------------------------------------------- 1 | import { ProductReader } from './Shop/Products/ProductRepository'; -------------------------------------------------------------------------------- /CH02/Figure-2-002.txt: -------------------------------------------------------------------------------- 1 | --dist 2 | |--README.md 3 | |--package.json 4 | |--src 5 | |--TypeSpec.d.ts 6 | |--TypeSpec.js 7 | |--... 8 | -------------------------------------------------------------------------------- /CH02/Listing-1-001.js: -------------------------------------------------------------------------------- 1 | var First; 2 | (function (First) { 3 | var Example = (function () { 4 | function Example() { 5 | } 6 | Example.prototype.log = function () { 7 | console.log('Logging from First.Example.log()'); 8 | }; 9 | return Example; 10 | }()); 11 | First.Example = Example; 12 | })(First || (First = {})); 13 | var Second; 14 | (function (Second) { 15 | var Example = (function () { 16 | function Example() { 17 | } 18 | Example.prototype.log = function () { 19 | console.log('Logging from Second.Example.log()'); 20 | }; 21 | return Example; 22 | }()); 23 | Second.Example = Example; 24 | })(Second || (Second = {})); 25 | var first = new First.Example(); 26 | // Logging from First.Example.log() 27 | first.log(); 28 | var second = new Second.Example(); 29 | // Logging from Second.Example.log() 30 | second.log(); 31 | -------------------------------------------------------------------------------- /CH02/Listing-2-000.ts: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /CH02/Listing-2-001.ts: -------------------------------------------------------------------------------- 1 | namespace First { 2 | export class Example { 3 | log() { 4 | console.log('Logging from First.Example.log()'); 5 | } 6 | } 7 | } 8 | 9 | namespace Second { 10 | export class Example { 11 | log() { 12 | console.log('Logging from Second.Example.log()'); 13 | } 14 | } 15 | } 16 | 17 | const first = new First.Example(); 18 | 19 | // Logging from First.Example.log() 20 | first.log(); 21 | 22 | const second = new Second.Example(); 23 | 24 | // Logging from Second.Example.log() 25 | second.log(); -------------------------------------------------------------------------------- /CH02/Listing-2-002.ts: -------------------------------------------------------------------------------- 1 | namespace FirstLevel { 2 | export namespace SecondLevel { 3 | export class Example { 4 | 5 | } 6 | } 7 | } 8 | 9 | namespace FirstLevel.SecondLevel.ThirdLevel { 10 | export class Example { 11 | 12 | } 13 | } 14 | 15 | const nested = new FirstLevel.SecondLevel.Example(); 16 | 17 | const dotted = new FirstLevel.SecondLevel.ThirdLevel.Example(); -------------------------------------------------------------------------------- /CH02/Listing-2-003.ts: -------------------------------------------------------------------------------- 1 | namespace Shipping { 2 | 3 | // Available as Shipping.Ship 4 | export interface Ship { 5 | name: string; 6 | port: string; 7 | displacement: number; 8 | } 9 | 10 | // Available as Shipping.Ferry 11 | export class Ferry implements Ship { 12 | constructor( 13 | public name: string, 14 | public port: string, 15 | public displacement: number) { 16 | } 17 | } 18 | 19 | // Only available inside of the Shipping module 20 | const defaultDisplacement = 4000; 21 | 22 | class PrivateShip implements Ship { 23 | constructor( 24 | public name: string, 25 | public port: string, 26 | public displacement: number = defaultDisplacement) { 27 | } 28 | } 29 | 30 | } 31 | 32 | const ferry = new Shipping.Ferry('Assurance', 'London', 3220); 33 | -------------------------------------------------------------------------------- /CH02/Listing-2-004.ts: -------------------------------------------------------------------------------- 1 | namespace Docking { 2 | import Ship = Shipping.Ship; 3 | 4 | export class Dock { 5 | private dockedShips: Ship[] = []; 6 | 7 | arrival(ship: Ship) { 8 | this.dockedShips.push(ship); 9 | } 10 | } 11 | } 12 | 13 | const dock = new Docking.Dock(); 14 | -------------------------------------------------------------------------------- /CH02/Listing-2-005.ts: -------------------------------------------------------------------------------- 1 | /// -------------------------------------------------------------------------------- /CH02/Listing-2-006.ts: -------------------------------------------------------------------------------- 1 | // Class/Namespace Merging 2 | class Car { 3 | 4 | } 5 | 6 | namespace Car { 7 | export class Engine { 8 | 9 | } 10 | 11 | export class GloveBox { 12 | 13 | } 14 | } 15 | 16 | const car = new Car(); 17 | const engine = new Car.Engine(); 18 | const gloveBox = new Car.GloveBox(); 19 | -------------------------------------------------------------------------------- /CH02/Listing-2-007.ts: -------------------------------------------------------------------------------- 1 | export interface Ship { 2 | name: string; 3 | port: string; 4 | displacement: number; 5 | } 6 | 7 | export class Ferry implements Ship { 8 | constructor( 9 | public name: string, 10 | public port: string, 11 | public displacement: number) { 12 | } 13 | } 14 | 15 | const defaultDisplacement = 4000; 16 | 17 | class PrivateShip implements Ship { 18 | constructor( 19 | public name: string, 20 | public port: string, 21 | public displacement: number = defaultDisplacement) { 22 | } 23 | } -------------------------------------------------------------------------------- /CH02/Listing-2-008.ts: -------------------------------------------------------------------------------- 1 | // Import entire module 2 | import * as Shipping from './Listing-2-007'; 3 | 4 | export class Dock { 5 | private dockedShips: Shipping.Ship[] = []; 6 | 7 | arrival(ship: Shipping.Ship) { 8 | this.dockedShips.push(ship); 9 | } 10 | } -------------------------------------------------------------------------------- /CH02/Listing-2-009.ts: -------------------------------------------------------------------------------- 1 | // Import a single export from a module 2 | import { Ship } from './Listing-2-007'; 3 | 4 | export class Dock { 5 | private dockedShips: Ship[] = []; 6 | 7 | arrival(ship: Ship) { 8 | this.dockedShips.push(ship); 9 | } 10 | } -------------------------------------------------------------------------------- /CH02/Listing-2-010.ts: -------------------------------------------------------------------------------- 1 | // Import using an alias 2 | import { Ship as Boat } from './Listing-2-007'; 3 | 4 | export class Dock { 5 | private dockedShips: Boat[] = []; 6 | 7 | arrival(ship: Boat) { 8 | this.dockedShips.push(ship); 9 | } 10 | } -------------------------------------------------------------------------------- /CH02/Listing-2-011.ts: -------------------------------------------------------------------------------- 1 | // Re-export with an alias 2 | export { Ship as Boat } from './Listing-2-007'; 3 | 4 | // Re-export an entire module 5 | export * from './Listing-2-008'; -------------------------------------------------------------------------------- /CH02/Listing-2-012.ts: -------------------------------------------------------------------------------- 1 | export default class Yacht { 2 | constructor( 3 | public name: string, 4 | public port: string, 5 | public displacement: number) { 6 | } 7 | } -------------------------------------------------------------------------------- /CH02/Listing-2-013.ts: -------------------------------------------------------------------------------- 1 | // Import a default export 2 | import Yacht from './Listing-2-012'; 3 | 4 | // Error: Module has no default export 5 | import Ship from './Listing-2-007'; 6 | 7 | const yacht = new Yacht('The Sea Princess', 'Tadley', 150); -------------------------------------------------------------------------------- /CH02/Listing-2-014.ts: -------------------------------------------------------------------------------- 1 | class Ferry { 2 | constructor( 3 | public name: string, 4 | public port: string, 5 | public displacement: number) { 6 | } 7 | } 8 | 9 | export = Ferry; -------------------------------------------------------------------------------- /CH02/Listing-2-015.ts: -------------------------------------------------------------------------------- 1 | import Ferry = require('./Listing-2-014'); 2 | 3 | const ferry = new Ferry('Dartmouth Ferry', 'Dartmouth', 580) -------------------------------------------------------------------------------- /CH02/Listing-2-016.ts: -------------------------------------------------------------------------------- 1 | // Declaration for the require function (Node) 2 | declare function require(moduleName: string): any; 3 | 4 | // Import - doesn't actually emit code 5 | import { Ferry } from './Listing-2-007'; 6 | 7 | const condition = true; 8 | 9 | if (condition) { 10 | // Only imports if the condition is true 11 | const ferry: typeof Ferry = require("./Listing-2-007"); 12 | 13 | const myFerry = new ferry('', '', 0); 14 | } -------------------------------------------------------------------------------- /CH02/Listing-2-017.ts: -------------------------------------------------------------------------------- 1 | // Declaration for the require function (Require JS) 2 | declare function require(moduleNames: string[], onLoad: (...args: any[]) => void): void; 3 | 4 | // Import - doesn't actually emit code 5 | import { Ferry } from './Listing-2-007'; 6 | 7 | const condition = true; 8 | 9 | if (condition) { 10 | // Only imports if the condition is true 11 | require(['./Listing-2-007'], (ferry: typeof Ferry) => { 12 | const myFerry = new ferry('', '', 0); 13 | }); 14 | } -------------------------------------------------------------------------------- /CH02/Listing-2-018.ts: -------------------------------------------------------------------------------- 1 | // Declaration for the require function (System JS) 2 | declare const System: { import(module: string): Promise; }; 3 | 4 | // Import - doesn't actually emit code 5 | import { Ferry } from './Listing-2-007'; 6 | 7 | const condition = true; 8 | 9 | if (condition) { 10 | // Only imports if the condition is true 11 | System.import('./Listing-2-007').then((ferry: typeof Ferry) => { 12 | const myFerry = new ferry('', '', 0); 13 | }); 14 | } -------------------------------------------------------------------------------- /CH02/Listing-2-019.txt: -------------------------------------------------------------------------------- 1 | # TypeSpec 2 | 3 | A TypeScript BDD framework. 4 | 5 | npm install typespec-bdd 6 | 7 | The aim is to properly separate the business specifications from the code, 8 | but rather than code-generate (like Java or C# BDD tools), the tests will be 9 | loaded and executed on the fly without converting the text into an 10 | intermediate language or framework. This should allow tests to be written using any 11 | unit testing framework - or even without one. 12 | -------------------------------------------------------------------------------- /CH02/Listing-2-020.txt: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Steve Fenton", 3 | "name": "typespec-bdd", 4 | "description": "BDD framework for TypeScript.", 5 | "keywords": [ 6 | "typespec", 7 | "typescript", 8 | "bdd", 9 | "behaviour", 10 | "driven" 11 | ], 12 | "version": "0.0.1", 13 | "homepage": "https://github.com/Steve-Fenton/TypeSpec", 14 | "bugs": "https://github.com/Steve-Fenton/TypeSpec/issues", 15 | "license": "(Apache-2.0)", 16 | "files": [ 17 | "src/" 18 | ], 19 | "repository": { 20 | "url": "https://github.com/Steve-Fenton/TypeSpec" 21 | }, 22 | "main": "src/TypeSpec.js", 23 | "types": "src/TypeSpec.d.ts", 24 | "dependencies": { }, 25 | "devDependencies": { }, 26 | "optionalDependencies": { }, 27 | "engines": { 28 | "node": "*" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CH02/Listing-2-021.txt: -------------------------------------------------------------------------------- 1 | XCOPY $(ProjectDir)Scripts\TypeSpec\*.d.ts $(ProjectDir)dist\src\ /y 2 | XCOPY $(ProjectDir)Scripts\TypeSpec\*.js $(ProjectDir)dist\src\ /y 3 | XCOPY $(SolutionDir)README.md $(ProjectDir)dist\ /y 4 | XCOPY $(ProjectDir)package.json $(ProjectDir)dist\ /y 5 | -------------------------------------------------------------------------------- /CH02/Listing-2-022.txt: -------------------------------------------------------------------------------- 1 | npm package -------------------------------------------------------------------------------- /CH02/Listing-2-023.txt: -------------------------------------------------------------------------------- 1 | npm publish -------------------------------------------------------------------------------- /CH02/Listing-2-024.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_2_024 { 2 | 3 | // Decorator Function 4 | function log(target: any, key: string, descriptor: any) { 5 | // square 6 | console.log(key); 7 | } 8 | 9 | class Calculator { 10 | // Using the decorator 11 | @log 12 | square(n: number) { 13 | return n * n; 14 | } 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /CH02/Listing-2-027.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_2_027 { 2 | 3 | function log(target: any) { 4 | const original = target; 5 | 6 | // Wrap the constructor with a logging constructor 7 | const constr: any = (...args) => { 8 | console.log(`Creating new ${original.name}`); 9 | const c: any = () => { 10 | return original.apply(null, args); 11 | } 12 | c.prototype = original.prototype; 13 | 14 | return new c(); 15 | } 16 | 17 | constr.prototype = original.prototype; 18 | 19 | return constr; 20 | } 21 | 22 | @log 23 | class Calculator { 24 | square(n: number) { 25 | return n * n; 26 | } 27 | } 28 | 29 | // Creating new Calculator 30 | var calc1 = new Calculator(); 31 | 32 | // Creating new Calculator 33 | var calc2 = new Calculator(); 34 | 35 | } -------------------------------------------------------------------------------- /CH02/Shop/Products/ProductRepository.ts: -------------------------------------------------------------------------------- 1 | export class ProductReader { 2 | 3 | } -------------------------------------------------------------------------------- /CH02/obj/Debug/CH02.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH02/obj/Debug/Chapter02.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH02/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH02/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH02/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH03/.vs/Chapter03/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH03/.vs/Chapter03/v15/.suo -------------------------------------------------------------------------------- /CH03/.vs/Chapter03/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH03/.vs/Chapter03/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH03/Listing-3-001.js: -------------------------------------------------------------------------------- 1 | // Assignment of different types 2 | let dynamic = 'A string'; 3 | 4 | dynamic = 52; 5 | 6 | // Operations with different types 7 | const days = '7'; 8 | const hours = 24; 9 | 10 | // 168 (luckily, the hours string is coerced) 11 | const week = days * hours; 12 | 13 | // 77 (concatenate 7 and 7) 14 | const fortnight = days + days; 15 | 16 | // Calling functions 17 | function getVolume(width, height, depth) { 18 | return width * height * depth; 19 | } 20 | 21 | // NaN (10 * undefined * undefined) 22 | const volumeA = getVolume(10); 23 | 24 | // 32 (the 8 is ignored) 25 | const volumeB = getVolume(2, 4, 4, 8); 26 | -------------------------------------------------------------------------------- /CH03/Listing-3-003.js: -------------------------------------------------------------------------------- 1 | var OrderedArray = (function () { 2 | function OrderedArray(comparer) { 3 | this.comparer = comparer; 4 | this.items = []; 5 | } 6 | OrderedArray.prototype.add = function (item) { 7 | this.items.push(item); 8 | this.items.sort(this.comparer); 9 | }; 10 | OrderedArray.prototype.getItem = function (index) { 11 | if (this.items.length > index) { 12 | return this.items[index]; 13 | } 14 | return null; 15 | }; 16 | return OrderedArray; 17 | }()); 18 | var orderedArray = new OrderedArray(); 19 | orderedArray.add(5); 20 | orderedArray.add(1); 21 | orderedArray.add(3); 22 | var firstItem = orderedArray.getItem(0); 23 | alert(firstItem); // 1 24 | -------------------------------------------------------------------------------- /CH03/Listing-3-003.ts: -------------------------------------------------------------------------------- 1 | class OrderedArray { 2 | private items: T[] = []; 3 | 4 | constructor(private comparer?: (a: T, b: T) => number) { 5 | } 6 | 7 | add(item: T): void { 8 | this.items.push(item); 9 | this.items.sort(this.comparer); 10 | } 11 | 12 | getItem(index: number): T { 13 | if (this.items.length > index) { 14 | return this.items[index]; 15 | } 16 | return null; 17 | } 18 | } 19 | 20 | var orderedArray: OrderedArray = new OrderedArray(); 21 | 22 | orderedArray.add(5); 23 | orderedArray.add(1); 24 | orderedArray.add(3); 25 | 26 | var firstItem: number = orderedArray.getItem(0); 27 | 28 | alert(firstItem); // 1 29 | -------------------------------------------------------------------------------- /CH03/Listing-3-004.js: -------------------------------------------------------------------------------- 1 | var OrderedArray = (function () { 2 | function OrderedArray(comparer) { 3 | this.comparer = comparer; 4 | this.items = []; 5 | } 6 | OrderedArray.prototype.add = function (item) { 7 | this.items.push(item); 8 | this.items.sort(this.comparer); 9 | }; 10 | OrderedArray.prototype.getItem = function (index) { 11 | if (this.items.length > index) { 12 | return this.items[index]; 13 | } 14 | return null; 15 | }; 16 | return OrderedArray; 17 | }()); 18 | var orderedArray = new OrderedArray(); 19 | orderedArray.add(5); 20 | orderedArray.add(1); 21 | orderedArray.add(3); 22 | var firstItem = orderedArray.getItem(0); 23 | alert(firstItem); // 1 24 | -------------------------------------------------------------------------------- /CH03/Listing-3-005.js: -------------------------------------------------------------------------------- 1 | function add(a, b) { 2 | /* The return value is used to determine 3 | the return type of the function */ 4 | return a + b; 5 | } 6 | // The cb parameter is inferred to be a function accepting a string 7 | var callsFunction = function (cb) { 8 | cb('Done'); 9 | // Supplied parameter does not match any signature of the call target 10 | // cb(1); 11 | }; 12 | // The result parameter is inferred to be a string 13 | callsFunction(function (result) { 14 | return result; 15 | }); 16 | -------------------------------------------------------------------------------- /CH03/Listing-3-005.ts: -------------------------------------------------------------------------------- 1 | function add(a: number, b: number) { 2 | /* The return value is used to determine 3 | the return type of the function */ 4 | return a + b; 5 | } 6 | 7 | interface CallsFunction { 8 | (cb: (result: string) => any): void; 9 | } 10 | 11 | // The cb parameter is inferred to be a function accepting a string 12 | var callsFunction: CallsFunction = function (cb) { 13 | cb('Done'); 14 | 15 | // Error: Argument of type '1' is not assignable to parameter of type 'string' 16 | cb(1); 17 | }; 18 | 19 | // The result parameter is inferred to be a string 20 | callsFunction(function (result) { 21 | return result; 22 | }); -------------------------------------------------------------------------------- /CH03/Listing-3-006.js: -------------------------------------------------------------------------------- 1 | // number[] 2 | var x = [0, 1, null]; 3 | // (string | number)[] 4 | var y = [0, 1, null, 'a']; 5 | -------------------------------------------------------------------------------- /CH03/Listing-3-006.ts: -------------------------------------------------------------------------------- 1 | // number[] 2 | let x = [0, 1, null]; 3 | 4 | // (string | number)[] 5 | let y = [0, 1, null, 'a']; -------------------------------------------------------------------------------- /CH03/Listing-3-007.js: -------------------------------------------------------------------------------- 1 | window.onclick = function (event) { 2 | var button = event.button; 3 | }; 4 | -------------------------------------------------------------------------------- /CH03/Listing-3-007.ts: -------------------------------------------------------------------------------- 1 | window.onclick = function (event) { 2 | var button = event.button; 3 | }; 4 | -------------------------------------------------------------------------------- /CH03/Listing-3-008.js: -------------------------------------------------------------------------------- 1 | function example() { 2 | return null; 3 | } 4 | var widened = example(); 5 | -------------------------------------------------------------------------------- /CH03/Listing-3-008.ts: -------------------------------------------------------------------------------- 1 | function example() { 2 | return null; 3 | } 4 | 5 | var widened = example(); -------------------------------------------------------------------------------- /CH03/Listing-3-009.ts: -------------------------------------------------------------------------------- 1 | interface DeviceMotionEvent extends Event { 2 | readonly acceleration: DeviceAcceleration | null; 3 | readonly accelerationIncludingGravity: DeviceAcceleration | null; 4 | readonly interval: number | null; 5 | readonly rotationRate: DeviceRotationRate | null; 6 | initDeviceMotionEvent(type: string, bubbles: boolean, cancelable: boolean, acceleration: DeviceAccelerationDict | null, accelerationIncludingGravity: DeviceAccelerationDict | null, rotationRate: DeviceRotationRateDict | null, interval: number | null): void; 7 | } 8 | 9 | declare var DeviceMotionEvent: { 10 | prototype: DeviceMotionEvent; 11 | new(typeArg: string, eventInitDict?: DeviceMotionEventInit): DeviceMotionEvent; 12 | }; -------------------------------------------------------------------------------- /CH03/Listing-3-010.js: -------------------------------------------------------------------------------- 1 | // The existing DeviceMotionEvent has all of its existing properties 2 | // plus our additional motionDescription property 3 | function handleMotionEvent(e) { 4 | var acceleration = e.acceleration; 5 | var description = e.motionDescription; 6 | } 7 | -------------------------------------------------------------------------------- /CH03/Listing-3-010.ts: -------------------------------------------------------------------------------- 1 | interface DeviceMotionEvent { 2 | motionDescription: string; 3 | } 4 | 5 | // The existing DeviceMotionEvent has all of its existing properties 6 | // plus our additional motionDescription property 7 | function handleMotionEvent(e: DeviceMotionEvent) { 8 | var acceleration = e.acceleration; 9 | var description = e.motionDescription; 10 | } -------------------------------------------------------------------------------- /CH03/Listing-3-011.ts: -------------------------------------------------------------------------------- 1 | function acceptNumber(input: number) { 2 | return input; 3 | } 4 | 5 | // number 6 | acceptNumber(1); 7 | 8 | // enum 9 | acceptNumber(Size.XL); 10 | 11 | // null 12 | acceptNumber(null); -------------------------------------------------------------------------------- /CH03/Listing-3-012.js: -------------------------------------------------------------------------------- 1 | var C1 = (function () { 2 | function C1() { 3 | } 4 | C1.prototype.show = function (hint) { 5 | return 1; 6 | }; 7 | return C1; 8 | }()); 9 | var C2 = (function () { 10 | function C2(name) { 11 | this.name = name; 12 | } 13 | C2.prototype.show = function (hint) { 14 | if (hint === void 0) { hint = 'default'; } 15 | return Math.floor(Math.random() * 10); 16 | }; 17 | return C2; 18 | }()); 19 | var C3 = (function () { 20 | function C3() { 21 | } 22 | C3.prototype.show = function () { 23 | return 'Dynamic'; 24 | }; 25 | return C3; 26 | }()); 27 | var T4 = { 28 | name: '', 29 | show: function () { 30 | return 1; 31 | } 32 | }; 33 | var c1 = new C1(); 34 | var c2 = new C2('A name'); 35 | var c3 = new C3(); 36 | // c1, c2, c3 and T4 are equivalent 37 | var arr = [c1, c2, c3, T4]; 38 | for (var i = 0; i < arr.length; i++) { 39 | arr[i].show(); 40 | } 41 | -------------------------------------------------------------------------------- /CH03/Listing-3-012.ts: -------------------------------------------------------------------------------- 1 | class C1 { 2 | name: string; 3 | 4 | show(hint?: string) { 5 | return 1; 6 | } 7 | } 8 | 9 | class C2 { 10 | constructor(public name: string) { 11 | 12 | } 13 | 14 | show(hint: string = 'default') { 15 | return Math.floor(Math.random() * 10); 16 | } 17 | } 18 | 19 | class C3 { 20 | name: string; 21 | 22 | show() { 23 | return 'Dynamic'; 24 | } 25 | } 26 | 27 | var T4 = { 28 | name: '', 29 | show() { 30 | return 1; 31 | } 32 | }; 33 | 34 | var c1 = new C1(); 35 | var c2 = new C2('A name'); 36 | var c3 = new C3(); 37 | 38 | // c1, c2, c3 and T4 are equivalent 39 | var arr: C1[] = [c1, c2, c3, T4]; 40 | 41 | for (var i = 0; i < arr.length; i++) { 42 | arr[i].show(); 43 | } 44 | -------------------------------------------------------------------------------- /CH03/Listing-3-013.js: -------------------------------------------------------------------------------- 1 | var Listing_3_13; 2 | (function (Listing_3_13) { 3 | $('#id').html('Hello World'); 4 | })(Listing_3_13 || (Listing_3_13 = {})); 5 | -------------------------------------------------------------------------------- /CH03/Listing-3-013.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_3_13 { 2 | declare var $: any; 3 | 4 | $('#id').html('Hello World'); 5 | } -------------------------------------------------------------------------------- /CH03/Listing-3-014.js: -------------------------------------------------------------------------------- 1 | var Listing_3_14; 2 | (function (Listing_3_14) { 3 | $('#id').html('Hello World'); 4 | })(Listing_3_14 || (Listing_3_14 = {})); 5 | -------------------------------------------------------------------------------- /CH03/Listing-3-014.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_3_14 { 2 | declare class jQuery { 3 | html(html: string): void; 4 | } 5 | 6 | declare function $(query: string): jQuery; 7 | 8 | $('#id').html('Hello World'); 9 | } -------------------------------------------------------------------------------- /CH03/Listing-3-13.js: -------------------------------------------------------------------------------- 1 | $('#id').html('Hello World'); 2 | -------------------------------------------------------------------------------- /CH03/obj/Debug/Chapter03.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH03/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH03/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH04/.vs/Chapter04/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH04/.vs/Chapter04/v15/.suo -------------------------------------------------------------------------------- /CH04/.vs/Chapter04/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH04/.vs/Chapter04/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH04/Listing-4-002.ts: -------------------------------------------------------------------------------- 1 | class Totalizer { 2 | private total = 0; 3 | private taxRateFactor = 0.2; 4 | 5 | addDonation(amount: number) { 6 | if (amount <= 0) { 7 | throw new Error('Donation exception'); 8 | } 9 | 10 | const taxRebate = amount * this.taxRateFactor; 11 | const totalDonation = amount + taxRebate; 12 | 13 | this.total += totalDonation; 14 | } 15 | 16 | getAmountRaised() { 17 | return this.total; 18 | } 19 | } 20 | 21 | const totalizer = new Totalizer(); 22 | 23 | totalizer.addDonation(100.00); 24 | 25 | const fundsRaised = totalizer.getAmountRaised(); 26 | 27 | // 120 28 | console.log(fundsRaised); 29 | -------------------------------------------------------------------------------- /CH04/Listing-4-004.ts: -------------------------------------------------------------------------------- 1 | interface Vehicle { 2 | moveTo(x: number, y: number); 3 | } 4 | 5 | // Explicit interface implementation 6 | class Car implements Vehicle { 7 | moveTo(x: number, y: number) { 8 | console.log('Driving to ' + x + ' ' + y); 9 | } 10 | } 11 | 12 | class SportsCar extends Car { 13 | 14 | } 15 | 16 | // Doesn't explicitly implement the Vehicle interface 17 | class Airplane { 18 | moveTo(x: number, y: number) { 19 | console.log('Flying to ' + x + ' ' + y); 20 | } 21 | } 22 | 23 | class Satellite { 24 | moveTo(x: number) { 25 | console.log('Targeting ' + x); 26 | } 27 | } 28 | 29 | function navigate(vehicle: Vehicle) { 30 | vehicle.moveTo(59.9436499, 10.7167959); 31 | } 32 | 33 | const car = new SportsCar(); 34 | navigate(car); 35 | 36 | const airplane = new Airplane(); 37 | navigate(airplane); 38 | 39 | const satellite = new Satellite(); 40 | navigate(satellite); -------------------------------------------------------------------------------- /CH04/Listing-4-005.ts: -------------------------------------------------------------------------------- 1 | declare class DataBase { 2 | static connect(credentials: string, articles: string[]): DataBase; 3 | movies: any; 4 | } 5 | 6 | namespace Listing_4_005 { 7 | class Movie { 8 | private db: DataBase; 9 | 10 | constructor(private title: string, private year: number) { 11 | this.db = DataBase.connect('user:pw@mydb', ['movies']); 12 | } 13 | 14 | getTitle() { 15 | return this.title + ' (' + this.year + ')'; 16 | } 17 | 18 | save() { 19 | this.db.movies.save({ title: this.title, year: this.year }); 20 | } 21 | } 22 | 23 | // Movie 24 | const movie = new Movie('The Internship', 2013); 25 | 26 | movie.save(); 27 | } -------------------------------------------------------------------------------- /CH04/Listing-4-006.ts: -------------------------------------------------------------------------------- 1 | class Movie { 2 | constructor(private title: string, private year: number) { 3 | } 4 | 5 | getTitle() { 6 | return this.title + ' (' + this.year + ')'; 7 | } 8 | } 9 | 10 | class MovieRepository { 11 | private db: DataBase; 12 | 13 | constructor() { 14 | this.db = DataBase.connect('user:pw@mydb', ['movies']); 15 | } 16 | 17 | save(movie: Movie) { 18 | this.db.movies.save(JSON.stringify(movie)); 19 | } 20 | } 21 | 22 | // Movie 23 | const movie = new Movie('The Internship', 2013); 24 | 25 | // MovieRepository 26 | const movieRepository = new MovieRepository(); 27 | 28 | movieRepository.save(movie); -------------------------------------------------------------------------------- /CH04/Listing-4-007.ts: -------------------------------------------------------------------------------- 1 | class RewardPointsCalculator { 2 | getPoints(transactionValue: number) { 3 | // 4 points per whole dollar spent 4 | return Math.floor(transactionValue) * 4; 5 | } 6 | } 7 | 8 | class DoublePointsCalculator extends RewardPointsCalculator { 9 | getPoints(transactionValue: number) { 10 | const standardPoints = super.getPoints(transactionValue); 11 | return standardPoints * 2; 12 | } 13 | } 14 | 15 | const pointsCalculator = new DoublePointsCalculator(); 16 | 17 | // 800 18 | alert(pointsCalculator.getPoints(100.99)); -------------------------------------------------------------------------------- /CH04/Listing-4-008.ts: -------------------------------------------------------------------------------- 1 | class ApplicationError implements Error { 2 | constructor(public name: string, public message: string) { 3 | 4 | } 5 | } 6 | 7 | throw new ApplicationError('Example Error', 'An error has occurred'); -------------------------------------------------------------------------------- /CH04/Listing-4-009.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_4_009 { 2 | interface Printer { 3 | copyDocument(); 4 | printDocument(document: Document); 5 | stapleDocument(document: Document, tray: number); 6 | } 7 | } -------------------------------------------------------------------------------- /CH04/Listing-4-010.ts: -------------------------------------------------------------------------------- 1 | interface Printer { 2 | printDocument(document: Document); 3 | } 4 | 5 | interface Stapler { 6 | stapleDocument(document: Document, tray: number); 7 | } 8 | 9 | interface Copier { 10 | copyDocument(); 11 | } 12 | 13 | class SimplePrinter implements Printer { 14 | printDocument(document: Document) { 15 | //... 16 | } 17 | } 18 | 19 | class SuperPrinter implements Printer, Stapler, Copier { 20 | printDocument(document: Document) { 21 | //... 22 | } 23 | 24 | copyDocument() { 25 | //... 26 | } 27 | 28 | stapleDocument(document: Document, tray: number) { 29 | //... 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CH04/Listing-4-011.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_4_011 { 2 | class Light { 3 | switchOn() { 4 | //... 5 | } 6 | 7 | switchOff() { 8 | //... 9 | } 10 | } 11 | 12 | class LightSwitch { 13 | private isOn = false; 14 | 15 | constructor(private light: Light) { 16 | } 17 | 18 | onPress() { 19 | if (this.isOn) { 20 | this.light.switchOff(); 21 | this.isOn = false; 22 | } else { 23 | this.light.switchOn(); 24 | this.isOn = true; 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CH04/Listing-4-012.ts: -------------------------------------------------------------------------------- 1 | interface LightSource { 2 | switchOn(); 3 | switchOff(); 4 | } 5 | 6 | class Light implements LightSource { 7 | switchOn() { 8 | //... 9 | } 10 | 11 | switchOff() { 12 | //... 13 | } 14 | } 15 | 16 | class LightSwitch { 17 | private isOn = false; 18 | 19 | constructor(private light: LightSource) { 20 | } 21 | 22 | onPress() { 23 | if (this.isOn) { 24 | this.light.switchOff(); 25 | this.isOn = false; 26 | } else { 27 | this.light.switchOn(); 28 | this.isOn = true; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /CH04/Listing-4-013.ts: -------------------------------------------------------------------------------- 1 | interface WheelCleaning { 2 | cleanWheels(): void; 3 | } 4 | 5 | class BasicWheelCleaning implements WheelCleaning { 6 | cleanWheels() { 7 | console.log('Soaping Wheel'); 8 | console.log('Brushing wheel'); 9 | } 10 | } 11 | 12 | class ExecutiveWheelCleaning extends BasicWheelCleaning { 13 | cleanWheels() { 14 | super.cleanWheels(); 15 | console.log('Waxing Wheel'); 16 | console.log('Rinsing Wheel'); 17 | } 18 | } -------------------------------------------------------------------------------- /CH04/Listing-4-014.ts: -------------------------------------------------------------------------------- 1 | interface BodyCleaning { 2 | cleanBody(): void; 3 | } 4 | 5 | class BasicBodyCleaning implements BodyCleaning { 6 | cleanBody() { 7 | console.log('Soaping car'); 8 | console.log('Rinsing Car'); 9 | } 10 | } 11 | 12 | class ExecutiveBodyCleaning extends BasicBodyCleaning { 13 | cleanBody() { 14 | super.cleanBody(); 15 | console.log('Waxing car'); 16 | console.log('Blow drying car'); 17 | } 18 | } -------------------------------------------------------------------------------- /CH04/Listing-4-016.ts: -------------------------------------------------------------------------------- 1 | interface ValetFactory { 2 | getWheelCleaning() : WheelCleaning; 3 | getBodyCleaning() : BodyCleaning; 4 | } -------------------------------------------------------------------------------- /CH04/Listing-4-017.ts: -------------------------------------------------------------------------------- 1 | class BronzeWashFactory implements ValetFactory { 2 | getWheelCleaning() { 3 | return new BasicWheelCleaning(); 4 | } 5 | 6 | getBodyCleaning() { 7 | return new BasicBodyCleaning(); 8 | } 9 | } 10 | 11 | class SilverWashFactory implements ValetFactory { 12 | getWheelCleaning() { 13 | return new BasicWheelCleaning(); 14 | } 15 | 16 | getBodyCleaning() { 17 | return new ExecutiveBodyCleaning(); 18 | } 19 | } 20 | 21 | class GoldWashFactory implements ValetFactory { 22 | getWheelCleaning() { 23 | return new ExecutiveWheelCleaning(); 24 | } 25 | 26 | getBodyCleaning() { 27 | return new ExecutiveBodyCleaning(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CH04/Listing-4-018.ts: -------------------------------------------------------------------------------- 1 | class CarWashProgram { 2 | constructor(private cleaningFactory: ValetFactory) { 3 | 4 | } 5 | 6 | runWash() { 7 | const wheelWash = this.cleaningFactory.getWheelCleaning(); 8 | wheelWash.cleanWheels(); 9 | 10 | const bodyWash = this.cleaningFactory.getBodyCleaning(); 11 | bodyWash.cleanBody(); 12 | } 13 | } -------------------------------------------------------------------------------- /CH04/Listing-4-019.ts: -------------------------------------------------------------------------------- 1 | function applyMixins(derivedCtor: any, baseCtors: any[]) { 2 | baseCtors.forEach(baseCtor => { 3 | Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { 4 | derivedCtor.prototype[name] = baseCtor.prototype[name]; 5 | }); 6 | }); 7 | } -------------------------------------------------------------------------------- /CH04/Listing-4-020.ts: -------------------------------------------------------------------------------- 1 | class Sings { 2 | sing() { 3 | console.log('Singing'); 4 | } 5 | } 6 | 7 | class Dances { 8 | dance() { 9 | console.log('Dancing'); 10 | } 11 | } 12 | 13 | class Acts { 14 | act() { 15 | console.log('Acting'); 16 | } 17 | } -------------------------------------------------------------------------------- /CH04/Listing-4-021.ts: -------------------------------------------------------------------------------- 1 | class Actor implements Acts { 2 | act: () => void; 3 | } 4 | 5 | applyMixins(Actor, [Acts]); 6 | 7 | class AllRounder implements Acts, Dances, Sings { 8 | act: () => void; 9 | dance: () => void; 10 | sing: () => void; 11 | } 12 | 13 | applyMixins(AllRounder, [Acts, Dances, Sings]); -------------------------------------------------------------------------------- /CH04/Listing-4-022.ts: -------------------------------------------------------------------------------- 1 | var actor = new Actor(); 2 | actor.act(); 3 | 4 | var allRounder = new AllRounder(); 5 | allRounder.act(); 6 | allRounder.dance(); 7 | allRounder.sing(); -------------------------------------------------------------------------------- /CH04/Listing-4-023.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_4_023 { 2 | class Acts { 3 | public message = 'Acting'; 4 | 5 | act() { 6 | console.log(this.message); 7 | } 8 | } 9 | 10 | class Actor implements Acts { 11 | public message: string; 12 | act: () => void; 13 | } 14 | 15 | applyMixins(Actor, [Acts]); 16 | 17 | const actor = new Actor(); 18 | 19 | // Logs 'undefined', not 'Acting' 20 | actor.act(); 21 | } -------------------------------------------------------------------------------- /CH04/Listing-4-024.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_4_024 { 2 | class Acts { 3 | public static message = 'Acting'; 4 | 5 | act() { 6 | alert(Acts.message); 7 | } 8 | } 9 | 10 | class Actor implements Acts { 11 | act: () => void; 12 | } 13 | 14 | applyMixins(Actor, [Acts]); 15 | 16 | const actor = new Actor(); 17 | 18 | // Logs 'Acting' 19 | actor.act(); 20 | } -------------------------------------------------------------------------------- /CH04/Listing-4-025.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_4_025 { 2 | type Constructor = new (...args: any[]) => T; 3 | 4 | function Acts(Base: TBase) { 5 | return class extends Base { 6 | message: string = 'Acting'; 7 | act() { 8 | alert(this.message); 9 | } 10 | }; 11 | } 12 | 13 | class Person { 14 | constructor(private name: string) { 15 | 16 | } 17 | } 18 | 19 | const Actor = Acts(Person); 20 | 21 | const actor = new Actor('Alan'); 22 | 23 | actor.act(); 24 | } -------------------------------------------------------------------------------- /CH04/obj/Debug/Appendix01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH04/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH04/obj/Debug/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH04/obj/Debug/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /CH04/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH04/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH04/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myproject", 3 | "version": "1.0.0", 4 | "devDependencies": { 5 | "@types/node": "^8.0.25" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /CH05/.vs/Chapter05/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH05/.vs/Chapter05/v15/.suo -------------------------------------------------------------------------------- /CH05/.vs/Chapter05/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH05/.vs/Chapter05/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH05/Listing-5-001.js: -------------------------------------------------------------------------------- 1 | var Listing_5_1; 2 | (function (Listing_5_1) { 3 | function test() { 4 | const testStart = performance.now(); 5 | window.setTimeout(function () { 6 | console.log(performance.now() - testStart); 7 | }, 50); 8 | } 9 | test(); 10 | })(Listing_5_1 || (Listing_5_1 = {})); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-001.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_1 { 2 | function test() { 3 | const testStart = performance.now(); 4 | 5 | window.setTimeout(function () { 6 | console.log(performance.now() - testStart); 7 | }, 50); 8 | } 9 | 10 | test(); 11 | } -------------------------------------------------------------------------------- /CH05/Listing-5-002.js: -------------------------------------------------------------------------------- 1 | function test() { 2 | const testStart = performance.now(); 3 | window.setTimeout(function () { 4 | console.log(performance.now() - testStart); 5 | }, 50); 6 | // Simulated long running process 7 | const start = +new Date(); 8 | while (+new Date() - start < 100) { 9 | // Delay for 100ms 10 | } 11 | } 12 | test(); 13 | -------------------------------------------------------------------------------- /CH05/Listing-5-002.ts: -------------------------------------------------------------------------------- 1 | function test() { 2 | const testStart = performance.now(); 3 | 4 | window.setTimeout(function () { 5 | console.log(performance.now() - testStart); 6 | }, 50); 7 | 8 | // Simulated long running process 9 | const start = +new Date(); 10 | while (+new Date() - start < 100) { 11 | // Delay for 100ms 12 | } 13 | } 14 | 15 | test(); -------------------------------------------------------------------------------- /CH05/Listing-5-003.js: -------------------------------------------------------------------------------- 1 | var Listing_5_3; 2 | (function (Listing_5_3) { 3 | var scope = 1; 4 | { 5 | var scope = 2; 6 | // Inner: 2 7 | console.log('Inner: ' + scope); 8 | } 9 | // Outer: 1 10 | console.log('Outer: ' + scope); 11 | })(Listing_5_3 || (Listing_5_3 = {})); 12 | -------------------------------------------------------------------------------- /CH05/Listing-5-003.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_3 { 2 | var scope = 1; 3 | 4 | { 5 | var scope = 2; 6 | 7 | // Inner: 2 8 | console.log('Inner: ' + scope); 9 | } 10 | 11 | // Outer: 1 12 | console.log('Outer: ' + scope); 13 | } -------------------------------------------------------------------------------- /CH05/Listing-5-004.js: -------------------------------------------------------------------------------- 1 | var Listing_5_4; 2 | (function (Listing_5_4) { 3 | var scope = 1; 4 | (function () { 5 | var scope = 2; 6 | // Inner: 2 7 | console.log('Inner: ' + scope); 8 | }()); 9 | // Outer: 1 10 | console.log('Outer: ' + scope); 11 | })(Listing_5_4 || (Listing_5_4 = {})); 12 | -------------------------------------------------------------------------------- /CH05/Listing-5-004.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_4 { 2 | var scope = 1; 3 | 4 | (function () { 5 | var scope = 2; 6 | 7 | // Inner: 2 8 | console.log('Inner: ' + scope); 9 | }()); 10 | 11 | // Outer: 1 12 | console.log('Outer: ' + scope); 13 | } -------------------------------------------------------------------------------- /CH05/Listing-5-005.js: -------------------------------------------------------------------------------- 1 | const scope = 1; 2 | { 3 | const scope = 2; 4 | // Inner: 2 5 | console.log('Inner: ' + scope); 6 | } 7 | // Outer: 1 8 | console.log('Outer: ' + scope); 9 | -------------------------------------------------------------------------------- /CH05/Listing-5-005.ts: -------------------------------------------------------------------------------- 1 | const scope = 1; 2 | 3 | { 4 | const scope = 2; 5 | 6 | // Inner: 2 7 | console.log('Inner: ' + scope); 8 | } 9 | 10 | // Outer: 1 11 | console.log('Outer: ' + scope); -------------------------------------------------------------------------------- /CH05/Listing-5-006.js: -------------------------------------------------------------------------------- 1 | var scope = 1; 2 | { 3 | var scope_1 = 2; 4 | // Inner: 2 5 | console.log('Inner: ' + scope_1); 6 | } 7 | // Outer: 1 8 | console.log('Outer: ' + scope); 9 | -------------------------------------------------------------------------------- /CH05/Listing-5-007.js: -------------------------------------------------------------------------------- 1 | function lemur() { 2 | console.log(kind); 3 | var kind = 'Ruffed Lemur'; 4 | } 5 | lemur(); 6 | -------------------------------------------------------------------------------- /CH05/Listing-5-007.ts: -------------------------------------------------------------------------------- 1 | function lemur() { 2 | // undefined, but technically allowable 3 | console.log(kind); 4 | 5 | var kind = 'Ruffed Lemur'; 6 | } 7 | 8 | lemur(); -------------------------------------------------------------------------------- /CH05/Listing-5-008.js: -------------------------------------------------------------------------------- 1 | var kind = 'Ring Tailed Lemur'; 2 | function lemur() { 3 | // undefined, not 'Ring Tailed Lemur' 4 | console.log(kind); 5 | var kind = 'Ruffed Lemur'; 6 | } 7 | lemur(); 8 | -------------------------------------------------------------------------------- /CH05/Listing-5-008.ts: -------------------------------------------------------------------------------- 1 | var kind = 'Ring Tailed Lemur'; 2 | 3 | function lemur() { 4 | // undefined, not 'Ring Tailed Lemur' 5 | console.log(kind); 6 | 7 | var kind = 'Ruffed Lemur'; 8 | } 9 | 10 | lemur(); -------------------------------------------------------------------------------- /CH05/Listing-5-009.js: -------------------------------------------------------------------------------- 1 | var Listing_5_9; 2 | (function (Listing_5_9) { 3 | function go(callback) { 4 | callback.call(this, 'Example Argument'); 5 | } 6 | function callbackFunction(arg) { 7 | alert(arg); 8 | } 9 | go(callbackFunction); 10 | })(Listing_5_9 || (Listing_5_9 = {})); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-009.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_9 { 2 | function go(callback: (arg: string) => void) { 3 | callback.call(this, 'Example Argument'); 4 | } 5 | 6 | function callbackFunction(arg: string) { 7 | alert(arg); 8 | } 9 | 10 | go(callbackFunction); 11 | } -------------------------------------------------------------------------------- /CH05/Listing-5-010.js: -------------------------------------------------------------------------------- 1 | var Listing_5_10; 2 | (function (Listing_5_10) { 3 | function go(callback) { 4 | callback.apply(this, ['Example Argument']); 5 | } 6 | function callbackFunction(arg) { 7 | alert(arg); 8 | } 9 | go(callbackFunction); 10 | })(Listing_5_10 || (Listing_5_10 = {})); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-010.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_10 { 2 | function go(callback: (arg: string) => void) { 3 | callback.apply(this, ['Example Argument']); 4 | } 5 | 6 | function callbackFunction(arg: string) { 7 | alert(arg); 8 | } 9 | 10 | go(callbackFunction); 11 | } -------------------------------------------------------------------------------- /CH05/Listing-5-011.js: -------------------------------------------------------------------------------- 1 | var Listing_5_11; 2 | (function (Listing_5_11) { 3 | function go(callback) { 4 | callback('Example Argument'); 5 | } 6 | function callbackFunction(arg) { 7 | alert(arg); 8 | } 9 | go(callbackFunction); 10 | })(Listing_5_11 || (Listing_5_11 = {})); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-011.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_11 { 2 | function go(callback: (arg: string) => void) { 3 | callback('Example Argument'); 4 | } 5 | 6 | function callbackFunction(arg: string) { 7 | alert(arg); 8 | } 9 | 10 | go(callbackFunction); 11 | } -------------------------------------------------------------------------------- /CH05/Listing-5-012.js: -------------------------------------------------------------------------------- 1 | const numbers = [3, 11, 5, 7, 2]; 2 | // A fragile way of finding the maximum number 3 | // const max = Math.max(numbers[0], numbers[1], numbers[2], numbers[3], numbers[4]); 4 | // A solid way to find the maximum 5 | const max = Math.max.apply(null, numbers); 6 | // 11 7 | console.log(max); 8 | -------------------------------------------------------------------------------- /CH05/Listing-5-012.ts: -------------------------------------------------------------------------------- 1 | const numbers = [3, 11, 5, 7, 2]; 2 | 3 | // A fragile way of finding the maximum number 4 | // const max = Math.max(numbers[0], numbers[1], numbers[2], numbers[3], numbers[4]); 5 | 6 | // A solid way to find the maximum 7 | const max = Math.max.apply(null, numbers); 8 | 9 | // 11 10 | console.log(max); -------------------------------------------------------------------------------- /CH05/Listing-5-013.js: -------------------------------------------------------------------------------- 1 | class Publisher { 2 | constructor() { 3 | this.subscribers = []; 4 | } 5 | addSubscriber(subscriber) { 6 | this.subscribers.push(subscriber); 7 | } 8 | notify(message) { 9 | for (let subscriber of this.subscribers) { 10 | subscriber(message); 11 | } 12 | } 13 | } 14 | const publisher = new Publisher(); 15 | // Using an arrow function 16 | publisher.addSubscriber((message) => console.log('A: ' + message)); 17 | // Using an inline function 18 | publisher.addSubscriber(function (message) { 19 | console.log('B: ' + message); 20 | }); 21 | // A: Test message 22 | // B: Test message 23 | publisher.notify('Test message'); 24 | -------------------------------------------------------------------------------- /CH05/Listing-5-013.ts: -------------------------------------------------------------------------------- 1 | interface Subscriber { 2 | (message: string): void; 3 | } 4 | 5 | class Publisher { 6 | private subscribers: Subscriber[] = []; 7 | 8 | addSubscriber(subscriber: Subscriber) { 9 | this.subscribers.push(subscriber); 10 | } 11 | 12 | notify(message: string) { 13 | for (let subscriber of this.subscribers) { 14 | subscriber(message); 15 | } 16 | } 17 | } 18 | 19 | const publisher = new Publisher(); 20 | 21 | // Using an arrow function 22 | publisher.addSubscriber((message) => console.log('A: ' + message)); 23 | 24 | // Using an inline function 25 | publisher.addSubscriber(function (message) { 26 | console.log('B: ' + message); 27 | }); 28 | 29 | // A: Test message 30 | // B: Test message 31 | publisher.notify('Test message'); -------------------------------------------------------------------------------- /CH05/Listing-5-026.js: -------------------------------------------------------------------------------- 1 | Promise.all([ 2 | FictitiousAPI.getData(1), 3 | FictitiousAPI.getData(2), 4 | FictitiousAPI.getData(3), 5 | FictitiousAPI.getData(4) 6 | ]).then((values) => { 7 | for (let val of values) { 8 | console.log(val.name); 9 | } 10 | }).catch((error) => { 11 | console.log('Caught ' + error); 12 | }); 13 | -------------------------------------------------------------------------------- /CH05/Listing-5-026.ts: -------------------------------------------------------------------------------- 1 | Promise.all([ 2 | FictitiousAPI.getData(1), 3 | FictitiousAPI.getData(2), 4 | FictitiousAPI.getData(3), 5 | FictitiousAPI.getData(4) 6 | ]).then((values) => { 7 | for (let val of values) { 8 | console.log(val.name); 9 | } 10 | }).catch((error) => { 11 | console.log('Caught ' + error); 12 | }); -------------------------------------------------------------------------------- /CH05/Listing-5-027.js: -------------------------------------------------------------------------------- 1 | Promise.race([ 2 | FictitiousAPI.getData(1), 3 | FictitiousAPI.getData(2), 4 | FictitiousAPI.getData(3), 5 | FictitiousAPI.getData(4) 6 | ]).then((data) => { 7 | console.log(data.name); 8 | }).catch((error) => { 9 | console.log('Caught ' + error); 10 | }); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-027.ts: -------------------------------------------------------------------------------- 1 | Promise.race([ 2 | FictitiousAPI.getData(1), 3 | FictitiousAPI.getData(2), 4 | FictitiousAPI.getData(3), 5 | FictitiousAPI.getData(4) 6 | ]).then((data) => { 7 | console.log(data.name); 8 | }).catch((error) => { 9 | console.log('Caught ' + error); 10 | }); -------------------------------------------------------------------------------- /CH05/Listing-5-028.js: -------------------------------------------------------------------------------- 1 | const request = new XMLHttpRequest(); 2 | request.onload = function () { 3 | if (request.status !== 200) { 4 | // Status code not likely to be usable, i.e. a redirect 5 | console.log('Status Code:', request.status); 6 | return; 7 | } 8 | const data = JSON.parse(request.responseText); 9 | console.log(data); 10 | }; 11 | request.onerror = (error) => { 12 | // Network failure or status code is error 13 | console.log('Error making request: ', error); 14 | }; 15 | request.open('get', './api/musketeers.json', true); 16 | request.send(); 17 | -------------------------------------------------------------------------------- /CH05/Listing-5-028.ts: -------------------------------------------------------------------------------- 1 | const request = new XMLHttpRequest(); 2 | 3 | request.onload = function () { 4 | if (request.status !== 200) { 5 | // Status code not likely to be usable, i.e. a redirect 6 | console.log('Status Code:', request.status); 7 | return; 8 | } 9 | 10 | const data = JSON.parse(request.responseText); 11 | console.log(data); 12 | }; 13 | 14 | request.onerror = (error) => { 15 | // Network failure or status code is error 16 | console.log('Error making request: ', error); 17 | }; 18 | 19 | request.open('get', './api/musketeers.json', true); 20 | request.send(); -------------------------------------------------------------------------------- /CH05/Listing-5-029.js: -------------------------------------------------------------------------------- 1 | fetch('./api/musketeers.json') 2 | .then((response) => { 3 | if (response.status !== 200) { 4 | // Status code not likely to be usable, i.e. a redirect or an error 5 | console.log('Status Code:', response.status); 6 | return; 7 | } 8 | return response.json(); 9 | }).then((data) => { 10 | console.log(data); 11 | }) 12 | .catch((error) => { 13 | // i.e. network failure 14 | console.log('Error making request', error); 15 | }); 16 | -------------------------------------------------------------------------------- /CH05/Listing-5-029.ts: -------------------------------------------------------------------------------- 1 | fetch('./api/musketeers.json') 2 | .then((response) => { 3 | if (response.status !== 200) { 4 | // Status code not likely to be usable, i.e. a redirect or an error 5 | console.log('Status Code:', response.status); 6 | return; 7 | } 8 | 9 | return response.json(); 10 | }).then((data) => { 11 | console.log(data); 12 | }) 13 | .catch((error) => { 14 | // i.e. network failure 15 | console.log('Error making request', error); 16 | }); 17 | -------------------------------------------------------------------------------- /CH05/Listing-5-030.js: -------------------------------------------------------------------------------- 1 | var Listing_5_30; 2 | (function (Listing_5_30) { 3 | class ClickLogger { 4 | constructor() { 5 | document.addEventListener('click', this.eventListener); 6 | } 7 | eventListener(e) { 8 | // 3 (Bubbling Phase) 9 | const phase = e.eventPhase; 10 | const tag = e.target.tagName; 11 | console.log(`Click event in phase ${phase} detected on element ${tag} by ClickLogger.`); 12 | } 13 | } 14 | const clickLogger = new ClickLogger(); 15 | })(Listing_5_30 || (Listing_5_30 = {})); 16 | -------------------------------------------------------------------------------- /CH05/Listing-5-030.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_30 { 2 | class ClickLogger { 3 | constructor() { 4 | document.addEventListener('click', this.eventListener); 5 | } 6 | 7 | eventListener(e: Event) { 8 | // 3 (Bubbling Phase) 9 | const phase = e.eventPhase; 10 | 11 | const tag = (e.target).tagName; 12 | 13 | console.log(`Click event in phase ${phase} detected on element ${tag} by ClickLogger.`); 14 | } 15 | } 16 | 17 | const clickLogger = new ClickLogger(); 18 | } -------------------------------------------------------------------------------- /CH05/Listing-5-031.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Event Demo 6 | 7 | 8 |
9 | Clicking on different parts of this document logs appropriate messages. 10 |
11 |

12 | Any fool can write code that a computer can understand. 13 | Good programmers write code that humans can understand. 14 |

15 |
16 | -Martin Fowler 17 |
18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /CH05/Listing-5-032.js: -------------------------------------------------------------------------------- 1 | function addEventCrossBrowser(element, eventName, listener) { 2 | if (element.addEventListener) { 3 | element.addEventListener(eventName, listener, false); 4 | } 5 | else if (element.attachEvent) { 6 | element.attachEvent('on' + eventName, listener); 7 | } 8 | } 9 | class ClickLogger { 10 | constructor() { 11 | addEventCrossBrowser(document, 'click', this.eventListener); 12 | } 13 | eventListener(e) { 14 | // 3 (Bubbling Phase) 15 | const phase = e.eventPhase; 16 | const tag = e.target.tagName; 17 | console.log('Click event detected on element ' + tag + ' by ClickLogger.'); 18 | } 19 | } 20 | const clickLogger = new ClickLogger(); 21 | -------------------------------------------------------------------------------- /CH05/Listing-5-032.ts: -------------------------------------------------------------------------------- 1 | function addEventCrossBrowser(element, eventName, listener) { 2 | if (element.addEventListener) { 3 | element.addEventListener(eventName, listener, false); 4 | } else if (element.attachEvent) { 5 | element.attachEvent('on' + eventName, listener); 6 | } 7 | } 8 | 9 | class ClickLogger { 10 | constructor() { 11 | addEventCrossBrowser(document, 'click', this.eventListener); 12 | } 13 | 14 | eventListener(e: Event) { 15 | // 3 (Bubbling Phase) 16 | const phase = e.eventPhase; 17 | 18 | const tag = (e.target).tagName; 19 | 20 | console.log('Click event detected on element ' + tag + ' by ClickLogger.'); 21 | } 22 | } 23 | 24 | const clickLogger = new ClickLogger(); -------------------------------------------------------------------------------- /CH05/Listing-5-034.js: -------------------------------------------------------------------------------- 1 | var Listing_5_34; 2 | (function (Listing_5_34) { 3 | NodeList.prototype.each = function (callback) { 4 | for (let node of this) { 5 | callback.call(node); 6 | } 7 | }; 8 | const getParagraphText = function () { 9 | console.log(this.innerHTML); 10 | }; 11 | const paragraphs = document.querySelectorAll('p'); 12 | paragraphs.each(getParagraphText); 13 | })(Listing_5_34 || (Listing_5_34 = {})); 14 | -------------------------------------------------------------------------------- /CH05/Listing-5-034.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_34 { 2 | NodeList.prototype.each = function (callback) { 3 | for (let node of this) { 4 | callback.call(node); 5 | } 6 | }; 7 | 8 | const getParagraphText = function () { 9 | console.log(this.innerHTML); 10 | }; 11 | 12 | const paragraphs = document.querySelectorAll('p'); 13 | paragraphs.each(getParagraphText); 14 | } -------------------------------------------------------------------------------- /CH05/Listing-5-035.js: -------------------------------------------------------------------------------- 1 | var Listing_5_35; 2 | (function (Listing_5_35) { 3 | NodeList.prototype.each = function (callback) { 4 | for (let node of this) { 5 | callback.call(node); 6 | } 7 | }; 8 | const getParagraphText = function () { 9 | console.log(this.innerHTML); 10 | }; 11 | const paragraphs = document.querySelectorAll('p'); 12 | paragraphs.each(getParagraphText); 13 | })(Listing_5_35 || (Listing_5_35 = {})); 14 | -------------------------------------------------------------------------------- /CH05/Listing-5-035.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_35 { 2 | interface NodeList { 3 | each(callback: () => any): void; 4 | } 5 | 6 | NodeList.prototype.each = function (callback) { 7 | for (let node of this) { 8 | callback.call(node); 9 | } 10 | }; 11 | 12 | const getParagraphText = function () { 13 | console.log(this.innerHTML); 14 | }; 15 | 16 | const paragraphs = document.querySelectorAll('p'); 17 | paragraphs.each(getParagraphText); 18 | } -------------------------------------------------------------------------------- /CH05/Listing-5-036.js: -------------------------------------------------------------------------------- 1 | NodeList.prototype.each = function (callback) { 2 | for (let node of this) { 3 | callback.call(node, node); 4 | } 5 | }; 6 | const getParagraphText = function (elem) { 7 | console.log(elem.innerHTML); 8 | }; 9 | const paragraphs = document.querySelectorAll('p'); 10 | paragraphs.each(getParagraphText); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-036.ts: -------------------------------------------------------------------------------- 1 | interface NodeList { 2 | each(callback: (element: HTMLElement) => any): void; 3 | } 4 | 5 | interface NodeListOf { 6 | each(callback: (element: TNode) => any): void; 7 | } 8 | 9 | NodeList.prototype.each = function (callback: (elem: HTMLElement) => any) { 10 | for (let node of this) { 11 | callback.call(node, node); 12 | } 13 | }; 14 | 15 | const getParagraphText = function (elem: HTMLParagraphElement) { 16 | console.log(elem.innerHTML); 17 | }; 18 | 19 | const paragraphs = document.querySelectorAll('p'); 20 | paragraphs.each(getParagraphText); -------------------------------------------------------------------------------- /CH05/Listing-5-037.js: -------------------------------------------------------------------------------- 1 | if (!NodeList.prototype.each) { 2 | NodeList.prototype.each = function (callback) { 3 | for (let node of this) { 4 | callback.call(node, node); 5 | } 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /CH05/Listing-5-037.ts: -------------------------------------------------------------------------------- 1 | if (!NodeList.prototype.each) { 2 | NodeList.prototype.each = function (callback: (elem: HTMLElement) => any) { 3 | for (let node of this) { 4 | callback.call(node, node); 5 | } 6 | }; 7 | } -------------------------------------------------------------------------------- /CH05/Listing-5-038.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_38 { 2 | class Lemur { 3 | constructor(public name: string) { 4 | 5 | } 6 | } 7 | 8 | const lemur = new Lemur('Sloth Lemur'); 9 | 10 | // new property 11 | lemur.isExtinct = true; 12 | 13 | // true 14 | console.log(lemur.isExtinct); 15 | } -------------------------------------------------------------------------------- /CH05/Listing-5-039.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_39 { 2 | class Lemur { 3 | constructor(public name: string) { 4 | 5 | } 6 | } 7 | 8 | const lemur = new Lemur('Sloth Lemur'); 9 | 10 | Object.seal(lemur); 11 | 12 | // new property 13 | lemur.isExtinct = true; 14 | 15 | // undefined 16 | console.log(lemur.isExtinct); 17 | } -------------------------------------------------------------------------------- /CH05/Listing-5-040.js: -------------------------------------------------------------------------------- 1 | var Listing_5_40; 2 | (function (Listing_5_40) { 3 | const elem = document.getElementById('example'); 4 | console.log(elem.classList); 5 | })(Listing_5_40 || (Listing_5_40 = {})); 6 | -------------------------------------------------------------------------------- /CH05/Listing-5-040.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_40 { 2 | const elem = document.getElementById('example'); 3 | 4 | console.log(elem.classList); 5 | } -------------------------------------------------------------------------------- /CH05/Listing-5-041.js: -------------------------------------------------------------------------------- 1 | var Listing_5_41; 2 | (function (Listing_5_41) { 3 | if (typeof document !== "undefined" && !("classList" in document.documentElement)) { 4 | const elementPrototype = (HTMLElement || Element).prototype; 5 | if (elementPrototype) { 6 | Object.defineProperty(elementPrototype, 'classList', { 7 | get: function () { 8 | const list = this.className ? this.className.split(/\s+/) : []; 9 | console.log('Polyfill: ' + list); 10 | } 11 | }); 12 | } 13 | } 14 | const elem = document.getElementById('example'); 15 | console.log(elem.classList); 16 | })(Listing_5_41 || (Listing_5_41 = {})); 17 | -------------------------------------------------------------------------------- /CH05/Listing-5-041.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_5_41 { 2 | if (typeof document !== "undefined" && !("classList" in document.documentElement)) { 3 | const elementPrototype = (HTMLElement || Element).prototype; 4 | if (elementPrototype) { 5 | Object.defineProperty(elementPrototype, 'classList', { 6 | get: function () { 7 | const list = this.className ? this.className.split(/\s+/) : []; 8 | console.log('Polyfill: ' + list); 9 | } 10 | }); 11 | } 12 | } 13 | 14 | const elem = document.getElementById('example'); 15 | 16 | console.log(elem.classList); 17 | } -------------------------------------------------------------------------------- /CH05/Listing-5-042.js: -------------------------------------------------------------------------------- 1 | class Elements { 2 | static getClassList(elem) { 3 | if ('classList' in elem) { 4 | return elem.classList; 5 | } 6 | return elem.className ? elem.className.split(/\s+/) : []; 7 | } 8 | } 9 | const elem = document.getElementById('example'); 10 | console.log(Elements.getClassList(elem)); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-042.ts: -------------------------------------------------------------------------------- 1 | class Elements { 2 | static getClassList(elem: HTMLElement) { 3 | if ('classList' in elem) { 4 | return elem.classList; 5 | } 6 | return elem.className ? elem.className.split(/\s+/) : []; 7 | } 8 | } 9 | 10 | const elem = document.getElementById('example'); 11 | 12 | console.log(Elements.getClassList(elem)); -------------------------------------------------------------------------------- /CH05/Listing-5-1.js: -------------------------------------------------------------------------------- 1 | var Listing_5_1; 2 | (function (Listing_5_1) { 3 | function test() { 4 | var testStart = performance.now(); 5 | window.setTimeout(function () { 6 | console.log(performance.now() - testStart); 7 | }, 50); 8 | } 9 | test(); 10 | })(Listing_5_1 || (Listing_5_1 = {})); 11 | -------------------------------------------------------------------------------- /CH05/Listing-5-2.js: -------------------------------------------------------------------------------- 1 | function test() { 2 | var testStart = performance.now(); 3 | window.setTimeout(function () { 4 | console.log(performance.now() - testStart); 5 | }, 50); 6 | // Simulated long running process 7 | var start = +new Date(); 8 | while (+new Date() - start < 100) { 9 | // Delay for 100ms 10 | } 11 | } 12 | test(); 13 | -------------------------------------------------------------------------------- /CH05/Listing-5-3.js: -------------------------------------------------------------------------------- 1 | var Listing_5_3; 2 | (function (Listing_5_3) { 3 | var scope = 1; 4 | { 5 | var scope = 2; 6 | // Inner: 2 7 | console.log('Inner: ' + scope); 8 | } 9 | // Outer: 1 10 | console.log('Outer: ' + scope); 11 | })(Listing_5_3 || (Listing_5_3 = {})); 12 | -------------------------------------------------------------------------------- /CH05/Listing-5-4.js: -------------------------------------------------------------------------------- 1 | var Listing_5_4; 2 | (function (Listing_5_4) { 3 | var scope = 1; 4 | (function () { 5 | var scope = 2; 6 | // Inner: 2 7 | console.log('Inner: ' + scope); 8 | }()); 9 | // Outer: 1 10 | console.log('Outer: ' + scope); 11 | })(Listing_5_4 || (Listing_5_4 = {})); 12 | -------------------------------------------------------------------------------- /CH05/Listing-5-5.js: -------------------------------------------------------------------------------- 1 | var scope = 1; 2 | { 3 | var scope_1 = 2; 4 | // Inner: 2 5 | console.log('Inner: ' + scope_1); 6 | } 7 | // Outer: 1 8 | console.log('Outer: ' + scope); 9 | -------------------------------------------------------------------------------- /CH05/obj/Debug/Appendix01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH05/obj/Debug/Chapter05.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH05/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH05/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH05/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH06/.vs/Chapter06/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH06/.vs/Chapter06/v15/.suo -------------------------------------------------------------------------------- /CH06/.vs/Chapter06/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH06/.vs/Chapter06/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH06/Listing-5-033.js: -------------------------------------------------------------------------------- 1 | function success(pos) { 2 | console.log('You are here: Lat=' + pos.coords.latitude + 3 | ' Long=' + pos.coords.longitude + 4 | ' Altitude=' + pos.coords.altitude + 5 | ' (Accuracy=' + pos.coords.altitudeAccuracy + ')' + 6 | ' Heading=' + pos.coords.heading + 7 | ' Speed=' + pos.coords.speed); 8 | } 9 | navigator.geolocation.getCurrentPosition(success); 10 | // You are here: Lat = 51.5033 Long = 0.1197 11 | // Altitude = 15 (Accuracy = 0) 12 | // Heading = 0 Speed = 0 13 | -------------------------------------------------------------------------------- /CH06/Listing-6-001.ts: -------------------------------------------------------------------------------- 1 | const image = document.getElementById('mainImage'); 2 | const container = document.getElementById('content'); 3 | 4 | function updateSizes() { 5 | // Flags the layout as invalid 6 | image.style.width = '50%'; 7 | 8 | // Causes a reflow to get the value 9 | const imageHeight = image.offsetHeight; 10 | 11 | // Flags the layout as invalid 12 | container.classList.add('highlight'); 13 | 14 | // Causes a reflow to get the value 15 | const containerHeight = container.offsetHeight; 16 | 17 | return { 18 | 'imageHeight': imageHeight, 19 | 'containerHeight': containerHeight 20 | }; 21 | } 22 | 23 | const result = updateSizes(); -------------------------------------------------------------------------------- /CH06/Listing-6-002.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_002 { 2 | const image = document.getElementById('mainImage'); 3 | const container = document.getElementById('content'); 4 | 5 | function updateSizes() { 6 | // Operations that invalidate the layout 7 | image.style.width = '50%'; 8 | container.classList.add('highlight'); 9 | 10 | // Operations that require a reflow 11 | const imageHeight = image.offsetHeight; 12 | const containerHeight = container.offsetHeight; 13 | 14 | return { 15 | 'imageHeight': imageHeight, 16 | 'containerHeight': containerHeight 17 | }; 18 | } 19 | 20 | const result = updateSizes(); 21 | } -------------------------------------------------------------------------------- /CH06/Listing-6-003.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Running in a Browser 6 | 7 | 8 | 9 |

Running in a Browser

10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /CH06/Listing-6-004.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_004 { 2 | // HTMLElement 3 | const a = document.getElementById('content'); 4 | 5 | // Element 6 | const b = document.querySelector('#content'); 7 | 8 | // HTMLDivElement (due to type assertion) 9 | const c = document.querySelector('#content'); 10 | } -------------------------------------------------------------------------------- /CH06/Listing-6-005.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_005 { 2 | // NodeListOf 3 | const elements = document.getElementsByTagName('div'); 4 | 5 | // HTMLDivElement 6 | const a = elements[0]; 7 | } -------------------------------------------------------------------------------- /CH06/Listing-6-006.ts: -------------------------------------------------------------------------------- 1 | // NodeListOf 2 | var elements = document.querySelectorAll('#content'); 3 | 4 | // Element 5 | var a = elements[0]; 6 | 7 | // HTMLDivElement 8 | var b = elements[0]; -------------------------------------------------------------------------------- /CH06/Listing-6-007.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_007 { 2 | function QueryOf(query: string) { 3 | return document.querySelector(query); 4 | } 5 | 6 | const elem = QueryOf('div#content'); 7 | 8 | function QueryAllOf(query: string) { 9 | return >document.querySelectorAll(query); 10 | } 11 | 12 | const elems = QueryAllOf('div'); 13 | } -------------------------------------------------------------------------------- /CH06/Listing-6-008.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_008 { 2 | const element = document.querySelector('#content'); 3 | 4 | element.innerHTML = 'Hello World'; 5 | } -------------------------------------------------------------------------------- /CH06/Listing-6-009.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_009 { 2 | const element = document.querySelector('#content'); 3 | 4 | // Create and add the first element 5 | const newElement1 = document.createElement('div'); 6 | newElement1.textContent = 'Hello World'; 7 | 8 | element.appendChild(newElement1); 9 | 10 | // Create and add the second element 11 | const newElement2 = document.createElement('div'); 12 | newElement2.textContent = 'Greetings Earth'; 13 | 14 | element.appendChild(newElement2); 15 | } -------------------------------------------------------------------------------- /CH06/Listing-6-010.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_010 { 2 | const element = document.querySelector('#content'); 3 | 4 | const newElement2 = document.createElement('div'); 5 | newElement2.textContent = 'Greetings Earth'; 6 | 7 | element.insertBefore(newElement2, element.firstChild); 8 | } -------------------------------------------------------------------------------- /CH06/Listing-6-012.ts: -------------------------------------------------------------------------------- 1 | export class Ajax { 2 | private readonly READY_STATUS_CODE = 4; 3 | 4 | private isCompleted(request: XMLHttpRequest) { 5 | return request.readyState === this.READY_STATUS_CODE; 6 | } 7 | 8 | httpGet(url: string) { 9 | return new Promise((resolve, reject) => { 10 | // Create a request 11 | const request = new XMLHttpRequest(); 12 | 13 | // Attach an event listener 14 | request.onreadystatechange = () => { 15 | if (this.isCompleted(request)) { 16 | resolve(request); 17 | } 18 | }; 19 | 20 | // Specify the HTTP verb and URL 21 | request.open('GET', url, true); 22 | 23 | // Send the request 24 | request.send(); 25 | }); 26 | } 27 | } -------------------------------------------------------------------------------- /CH06/Listing-6-014.ts: -------------------------------------------------------------------------------- 1 | import { Ajax } from './Listing-6-013'; 2 | 3 | var ajax = new Ajax(); 4 | 5 | // Making a GET request 6 | ajax.httpGet('data.html') 7 | .then((request) => { 8 | document.getElementById('content').innerHTML = request.responseText; 9 | }); -------------------------------------------------------------------------------- /CH06/Listing-6-015.ts: -------------------------------------------------------------------------------- 1 | const request = new XMLHttpRequest(); 2 | request.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 3 | // ... -------------------------------------------------------------------------------- /CH06/Listing-6-016.ts: -------------------------------------------------------------------------------- 1 | const webSocket = new WebSocket('ws://localhost:8080/WS'); 2 | 3 | webSocket.onmessage = (message: MessageEvent) => { 4 | // Log message from server 5 | console.log(message.data); 6 | } 7 | 8 | webSocket.send('Message To Server'); -------------------------------------------------------------------------------- /CH06/Listing-6-017.ts: -------------------------------------------------------------------------------- 1 | const constraints = { 2 | audio: true, 3 | video: { 4 | width: 1280, 5 | height: 720 6 | } 7 | }; 8 | 9 | const videoElement = document.createElement('video'); 10 | videoElement.setAttribute('width', Math.floor(constraints.video.width / 2).toString()); 11 | videoElement.setAttribute('height', Math.floor(constraints.video.height / 2).toString()); 12 | document.body.appendChild(videoElement); 13 | 14 | navigator.mediaDevices.getUserMedia(constraints) 15 | .then(function (mediaStream) { 16 | const video = document.querySelector('video'); 17 | video.srcObject = mediaStream; 18 | video.onloadedmetadata = function (e) { 19 | video.play(); 20 | }; 21 | }) 22 | .catch(function (error) { 23 | console.log(error.name, error.message); 24 | }); -------------------------------------------------------------------------------- /CH06/Listing-6-018.ts: -------------------------------------------------------------------------------- 1 | const storageKey = 'Example'; 2 | 3 | // null the first time, 'Stored value' each subsequent time 4 | console.log(sessionStorage.getItem(storageKey)); 5 | 6 | sessionStorage.setItem(storageKey, 'Stored value'); -------------------------------------------------------------------------------- /CH06/Listing-6-019.ts: -------------------------------------------------------------------------------- 1 | // Remove an item using a key 2 | sessionStorage.removeItem(storageKey); 3 | 4 | // Clear all items 5 | sessionStorage.clear(); -------------------------------------------------------------------------------- /CH06/Listing-6-020.ts: -------------------------------------------------------------------------------- 1 | import { addEvent } from './Listing-6-011'; 2 | 3 | const storageKey = 'Example'; 4 | 5 | localStorage.setItem(storageKey, 'Stored value ' + Date.now()); 6 | 7 | addEvent(window, 'storage', (event: StorageEvent) => { 8 | console.log(`${event.key} "${event.oldValue}" changed to "${event.newValue}"`); 9 | }); -------------------------------------------------------------------------------- /CH06/Listing-6-021.ts: -------------------------------------------------------------------------------- 1 | export class Product { 2 | constructor(public productId: number, public name: string) { 3 | 4 | } 5 | } -------------------------------------------------------------------------------- /CH06/Listing-6-022.ts: -------------------------------------------------------------------------------- 1 | import { Product } from './Listing-6-021'; 2 | 3 | export class ProductDatabase { 4 | constructor(private name: string, private version: number) { 5 | } 6 | } -------------------------------------------------------------------------------- /CH06/Listing-6-024.ts: -------------------------------------------------------------------------------- 1 | import { ProductDatabase } from './Listing-6-023'; 2 | 3 | const versionNumber = 1; 4 | 5 | const db = new ProductDatabase('ExampleDatabase', versionNumber); -------------------------------------------------------------------------------- /CH06/Listing-6-026.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | IndexedDB 6 | 7 | 8 | 9 |

IndexedDB

10 |
11 | 12 |
13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CH06/Listing-6-027.ts: -------------------------------------------------------------------------------- 1 | import { addEvent } from './Listing-6-011'; 2 | import { Product } from './Listing-6-021'; 3 | import { ProductDatabase } from './Listing-6-025'; 4 | 5 | const db = new ProductDatabase('ExampleDatabase', 1); 6 | 7 | // Wait for entry in the productId input 8 | addEvent(document.getElementById('productId'), 'keyup', function () { 9 | // Get the id entered by the user, convert to number 10 | const productId = +this.value; 11 | 12 | // Search the database with the id 13 | db.getProduct(productId, (product) => { 14 | document.getElementById('content').innerHTML = product ? 15 | `The result for product id: ${product.productId} is: ${product.name}` : 16 | 'No result'; 17 | }); 18 | }); -------------------------------------------------------------------------------- /CH06/Listing-6-029.ts: -------------------------------------------------------------------------------- 1 | import { Product } from './Listing-6-021'; 2 | import { ProductDatabase } from './Listing-6-028'; 3 | 4 | const db = new ProductDatabase('ExampleDatabase', 1); 5 | 6 | const newProduct = new Product(4, 'Newly added product'); 7 | 8 | db.addProduct(newProduct); -------------------------------------------------------------------------------- /CH06/Listing-6-031.ts: -------------------------------------------------------------------------------- 1 | import { Product } from './Listing-6-021'; 2 | import { ProductDatabase } from './Listing-6-030'; 3 | 4 | const db = new ProductDatabase('ExampleDatabase', 1); 5 | 6 | db.deleteProduct(4); -------------------------------------------------------------------------------- /CH06/Listing-6-033.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_033 { 2 | function success(pos: Position) { 3 | console.log('You are here: Lat=' + pos.coords.latitude + 4 | ' Long=' + pos.coords.longitude + 5 | ' Altitude=' + pos.coords.altitude + 6 | ' (Accuracy=' + pos.coords.altitudeAccuracy + ')' + 7 | ' Heading=' + pos.coords.heading + 8 | ' Speed=' + pos.coords.speed); 9 | } 10 | 11 | navigator.geolocation.getCurrentPosition(success); 12 | 13 | // You are here: Lat = 51.5033 Long = 0.1197 14 | // Altitude = 15 (Accuracy = 0) 15 | // Heading = 0 Speed = 0 16 | } -------------------------------------------------------------------------------- /CH06/Listing-6-034.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_034 { 2 | function success(pos: Position) { 3 | console.log('You are here: Lat=' + pos.coords.latitude + 4 | ' Long=' + pos.coords.longitude + 5 | ' Altitude=' + pos.coords.altitude + 6 | ' (Accuracy=' + pos.coords.altitudeAccuracy + ')' + 7 | ' Heading=' + pos.coords.heading + 8 | ' Speed=' + pos.coords.speed); 9 | } 10 | 11 | const watch = navigator.geolocation.watchPosition(success); 12 | 13 | // You are here: Lat = 51.5033 Long = 0.1197 14 | // Altitude = 135 (Accuracy = 15) 15 | // Heading = 0 Speed = 0 16 | 17 | // You are here: Lat = 51.5144 Long = 0.0803 18 | // Altitude = 180 (Accuracy = 15) 19 | // Heading = 60 Speed = 3379 20 | } -------------------------------------------------------------------------------- /CH06/Listing-6-035.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_035 { 2 | function success(pos: Position) { 3 | console.log('You are here: Lat=' + pos.coords.latitude + 4 | ' Long=' + pos.coords.longitude + 5 | ' Altitude=' + pos.coords.altitude + 6 | ' (Accuracy=' + pos.coords.altitudeAccuracy + ')' + 7 | ' Heading=' + pos.coords.heading + 8 | ' Speed=' + pos.coords.speed); 9 | } 10 | 11 | const watch = navigator.geolocation.watchPosition(success); 12 | 13 | navigator.geolocation.clearWatch(watch); 14 | 15 | // You are here: Lat = 51.5033 Long = 0.1197 16 | // Altitude = 135 (Accuracy = 15) 17 | // Heading = 0 Speed = 0 18 | 19 | // You are here: Lat = 51.5144 Long = 0.0803 20 | // Altitude = 180 (Accuracy = 15) 21 | // Heading = 60 Speed = 3379 22 | } -------------------------------------------------------------------------------- /CH06/Listing-6-036.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_036 { 2 | function success() { 3 | console.log('Okay'); 4 | } 5 | 6 | function error() { 7 | console.log('Position information not available.'); 8 | } 9 | 10 | const watch = navigator.geolocation.watchPosition(success, error); 11 | } -------------------------------------------------------------------------------- /CH06/Listing-6-037.ts: -------------------------------------------------------------------------------- 1 | interface BatteryManager { 2 | charging: boolean; 3 | chargingTime: number; 4 | dischargingTime: number; 5 | level: number; 6 | onchargingchange: () => any; 7 | onchargingtimechange: () => any; 8 | ondischargingtimechange: () => any; 9 | onlevelchange: () => any; 10 | } 11 | 12 | interface Navigator { 13 | battery: BatteryManager; 14 | mozBattery: BatteryManager; 15 | webkitBattery: BatteryManager; 16 | } -------------------------------------------------------------------------------- /CH06/Listing-6-039.ts: -------------------------------------------------------------------------------- 1 | import { addEvent } from './Listing-6-011'; 2 | 3 | interface ProximityEvent { 4 | min: number; 5 | max: number; 6 | value: number; 7 | near: boolean; 8 | } 9 | 10 | const output = document.getElementById('content'); 11 | 12 | function sensorChange(proximity: ProximityEvent) { 13 | const distance = 14 | (proximity.value ? proximity.value + ' ' : '') + 15 | (proximity.near ? 'near' : 'far'); 16 | 17 | output.innerHTML = distance; 18 | } 19 | 20 | // Near or far 21 | addEvent(window, 'userproximity', sensorChange); 22 | 23 | // Measurement within a range 24 | addEvent(window, 'deviceproximity', sensorChange); -------------------------------------------------------------------------------- /CH06/Listing-6-040.ts: -------------------------------------------------------------------------------- 1 | import { addEvent } from './Listing-6-011'; 2 | 3 | const output = document.getElementById('content'); 4 | 5 | function sensorChange(data: DeviceLightEvent) { 6 | output.innerHTML = 'Ambient light reading: ' + data.value; 7 | } 8 | 9 | addEvent(window, 'devicelight', sensorChange); -------------------------------------------------------------------------------- /CH06/Listing-6-041.ts: -------------------------------------------------------------------------------- 1 | import { addEvent } from './Listing-6-011'; 2 | 3 | const output = document.getElementById('content'); 4 | 5 | function sensorChange(event: DeviceMotionEvent) { 6 | var motion = event.acceleration; 7 | var rotation = event.rotationRate; 8 | 9 | output.innerHTML = '

Motion :
' + 10 | motion.x + '
' + 11 | motion.y + '
' + 12 | motion.z + '

' + 13 | '

Rotation:
' + 14 | rotation.alpha + '
' + 15 | rotation.beta + '
' + 16 | rotation.gamma + '

'; 17 | } 18 | 19 | addEvent(window, 'devicemotion', sensorChange); -------------------------------------------------------------------------------- /CH06/Listing-6-042.ts: -------------------------------------------------------------------------------- 1 | import { addEvent } from './Listing-6-011'; 2 | 3 | const sensorApiName = 'devicetemperature'; 4 | 5 | const output = document.getElementById('content'); 6 | 7 | addEvent(window, sensorApiName, (data) => { 8 | output.innerHTML = sensorApiName + ' ' + data.value; 9 | }); -------------------------------------------------------------------------------- /CH06/Listing-6-043.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_043 { 2 | declare function postMessage(message: any): void; 3 | 4 | let id = 0; 5 | 6 | self.setInterval(() => { 7 | id++; 8 | var message = { 9 | 'id': id, 10 | 'message': 'Message sent at ' + Date.now() 11 | }; 12 | 13 | postMessage(message); 14 | }, 1000); 15 | } -------------------------------------------------------------------------------- /CH06/Listing-6-044.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_6_044 { 2 | const worker = new Worker('/Listing-6-043.js'); 3 | 4 | function workerMessageReceived(event) { 5 | const response = event.data; 6 | 7 | console.log(response.id, response.message); 8 | }; 9 | 10 | worker.addEventListener('message', workerMessageReceived); 11 | } -------------------------------------------------------------------------------- /CH06/Listing-6-045.ts: -------------------------------------------------------------------------------- 1 | declare function postMessage(message: any): void; 2 | 3 | let id = 0; 4 | 5 | function start() { 6 | self.setInterval(() => { 7 | id++; 8 | const message = { 9 | 'id': id, 10 | 'message': 'Message sent at ' + Date.now() 11 | }; 12 | 13 | postMessage(message); 14 | }, 1000); 15 | } 16 | 17 | self.onmessage = (event) => { 18 | if (event.data === 'Start') { 19 | start(); 20 | } else { 21 | console.log(event.data); 22 | } 23 | } -------------------------------------------------------------------------------- /CH06/Listing-6-046.ts: -------------------------------------------------------------------------------- 1 | const worker = new Worker('/Listing-6-045.js'); 2 | 3 | function workerMessageReceived(event) { 4 | const response = event.data; 5 | 6 | console.log(response.id, response.message); 7 | }; 8 | 9 | worker.addEventListener('message', workerMessageReceived); 10 | 11 | worker.postMessage('Start'); -------------------------------------------------------------------------------- /CH06/WORKERS.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Web Workers 6 | 7 | 8 | 9 |

Web Workes

10 |
11 | Open the browser console... 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /CH06/obj/Debug/Appendix01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH06/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH06/obj/Debug/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH06/obj/Debug/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /CH06/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH06/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH06/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myproject", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "requirejs": "^2.3.5" 6 | }, 7 | "devDependencies": { 8 | "@types/requirejs": "^2.1.31", 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CH07/.vs/Chapter07/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH07/.vs/Chapter07/v15/.suo -------------------------------------------------------------------------------- /CH07/NodeApp/Chapter07.njsproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ProjectFiles 5 | 6 | -------------------------------------------------------------------------------- /CH07/NodeApp/README.md: -------------------------------------------------------------------------------- 1 | # NodeApp 2 | 3 | 4 | -------------------------------------------------------------------------------- /CH07/NodeApp/obj/Debug/Chapter07.njsproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\steve\OneDrive\Books\Pro TypeScript 2nd\2ndEditionCode\CH7\NodeApp\obj\Debug\Chapter07.njsprojResolveAssemblyReference.cache 2 | C:\Users\steve\OneDrive\Books\Pro TypeScript 2nd\2ndEditionCode\CH7\NodeApp\obj\Debug\Chapter07.njsproj.CoreCompileInputs.cache 3 | C:\Users\steve\OneDrive\Books\Pro TypeScript 2nd\2ndEditionCode\CH7\NodeApp\bin\Microsoft.NodejsTools.WebRole.dll 4 | -------------------------------------------------------------------------------- /CH07/NodeApp/obj/Debug/NodeApp.njsproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 07e3dfdc747d235400f294e34b8edca0edec755d 2 | -------------------------------------------------------------------------------- /CH07/NodeApp/obj/Debug/NodeApp.njsproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\Steve.Fenton.GERONIMO\Source\Repos\NodeApp\NodeApp\obj\Debug\NodeApp.njsprojResolveAssemblyReference.cache 2 | C:\Users\Steve.Fenton.GERONIMO\Source\Repos\NodeApp\NodeApp\obj\Debug\NodeApp.njsproj.CoreCompileInputs.cache 3 | C:\Users\Steve.Fenton.GERONIMO\Source\Repos\NodeApp\NodeApp\bin\Microsoft.NodejsTools.WebRole.dll 4 | -------------------------------------------------------------------------------- /CH07/NodeApp/obj/Debug/NodeApp.njsprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH07/NodeApp/obj/Debug/NodeApp.njsprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /CH07/NodeApp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pro-typescript-book-app", 3 | "version": "0.0.1", 4 | "description": "An example book application", 5 | "main": "server.js", 6 | "types": "server.d.ts", 7 | "author": { 8 | "name": "Steve.Fenton" 9 | }, 10 | "dependencies": { 11 | "body-parser": "1.17.2", 12 | "express": "4.15.4", 13 | "method-override": "2.3.9", 14 | "mongoose": "4.11.9", 15 | "pug": "2.0.0-rc.3" 16 | }, 17 | "devDependencies": { 18 | "@types/body-parser": "1.16.5", 19 | "@types/express": "4.0.37", 20 | "@types/method-override": "0.0.30", 21 | "@types/mongoose": "4.7.21", 22 | "@types/node": "8.0.26", 23 | "@types/pug": "2.0.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CH07/NodeApp/routes/index.ts: -------------------------------------------------------------------------------- 1 | import * as express from 'express'; 2 | 3 | /* GET home page. */ 4 | export function index(request: express.Request, response: express.Response) { 5 | response.render('index', { title: 'Express' }); 6 | }; -------------------------------------------------------------------------------- /CH07/NodeApp/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } -------------------------------------------------------------------------------- /CH07/NodeApp/views/index.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | a(href='/book') Books -------------------------------------------------------------------------------- /CH07/NodeApp/views/layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/style.css') 6 | body 7 | block content -------------------------------------------------------------------------------- /CH08/.vs/Chapter08/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH08/.vs/Chapter08/v15/.suo -------------------------------------------------------------------------------- /CH08/.vs/Chapter08/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH08/.vs/Chapter08/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH08/Listing-8-001.js: -------------------------------------------------------------------------------- 1 | var Listing_8_001; 2 | (function (Listing_8_001) { 3 | function errorsOnThree(input) { 4 | if (input === 3) { 5 | throw new Error('Three is not allowed'); 6 | } 7 | return input; 8 | } 9 | var result = errorsOnThree(3); 10 | })(Listing_8_001 || (Listing_8_001 = {})); 11 | -------------------------------------------------------------------------------- /CH08/Listing-8-001.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_8_001 { 2 | function errorsOnThree(input: number) { 3 | if (input === 3) { 4 | throw new Error('Three is not allowed'); 5 | } 6 | 7 | return input; 8 | } 9 | 10 | const result = errorsOnThree(3); 11 | } -------------------------------------------------------------------------------- /CH08/Listing-8-002.js: -------------------------------------------------------------------------------- 1 | var Listing_8_002; 2 | (function (Listing_8_002) { 3 | var ApplicationError = /** @class */ (function () { 4 | function ApplicationError(message) { 5 | this.message = message; 6 | this.name = 'ApplicationError'; 7 | if (typeof console !== 'undefined') { 8 | console.log("Creating " + this.name + " \"" + message + "\""); 9 | } 10 | } 11 | ApplicationError.prototype.toString = function () { 12 | return this.name + ": {this.message}"; 13 | }; 14 | return ApplicationError; 15 | }()); 16 | })(Listing_8_002 || (Listing_8_002 = {})); 17 | -------------------------------------------------------------------------------- /CH08/Listing-8-002.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_8_002 { 2 | class ApplicationError implements Error { 3 | 4 | public name = 'ApplicationError'; 5 | 6 | constructor(public message: string) { 7 | if (typeof console !== 'undefined') { 8 | console.log(`Creating ${this.name} "${message}"`); 9 | } 10 | } 11 | 12 | toString() { 13 | return `${this.name}: {this.message}`; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /CH08/Listing-8-003.ts: -------------------------------------------------------------------------------- 1 | class ApplicationError implements Error { 2 | 3 | public name = 'ApplicationError'; 4 | 5 | constructor(public message: string) { 6 | if (typeof console !== 'undefined') { 7 | console.log(`Creating ${this.name} "${message}"`); 8 | } 9 | } 10 | 11 | toString() { 12 | return `${this.name}: {this.message}`; 13 | } 14 | } 15 | 16 | class InputError extends ApplicationError { 17 | } 18 | 19 | function errorsOnThree(input: number) { 20 | if (input === 3) { 21 | throw new InputError('Three is not allowed'); 22 | } 23 | 24 | return input; 25 | } -------------------------------------------------------------------------------- /CH08/Listing-8-004.js: -------------------------------------------------------------------------------- 1 | try { 2 | var result = errorsOnThree(3); 3 | } 4 | catch (err) { 5 | console.log('Error caught, no action taken'); 6 | } 7 | -------------------------------------------------------------------------------- /CH08/Listing-8-004.ts: -------------------------------------------------------------------------------- 1 | try { 2 | const result = errorsOnThree(3); 3 | } catch (err) { 4 | console.log('Error caught, no action taken'); 5 | } -------------------------------------------------------------------------------- /CH08/Listing-8-005.js: -------------------------------------------------------------------------------- 1 | try { 2 | var result = errorsOnThree(3); 3 | } 4 | catch (err) { 5 | if (err instanceof ApplicationError) { 6 | console.log('Error caught, no action taken'); 7 | } 8 | throw err; 9 | } 10 | -------------------------------------------------------------------------------- /CH08/Listing-8-005.ts: -------------------------------------------------------------------------------- 1 | try { 2 | const result = errorsOnThree(3); 3 | } catch (err) { 4 | if (err instanceof ApplicationError) { 5 | console.log('Error caught, no action taken'); 6 | } 7 | 8 | throw err; 9 | } 10 | -------------------------------------------------------------------------------- /CH08/Listing-8-006.js: -------------------------------------------------------------------------------- 1 | var sensorChange = function (reading) { 2 | var proximity = reading.near 3 | ? 'Near' 4 | : 'Far'; 5 | alert(proximity); 6 | }; 7 | window.addEventListener('userproximity', sensorChange, true); 8 | -------------------------------------------------------------------------------- /CH08/Listing-8-006.ts: -------------------------------------------------------------------------------- 1 | const sensorChange = function (reading) { 2 | const proximity = reading.near 3 | ? 'Near' 4 | : 'Far'; 5 | 6 | alert(proximity); 7 | } 8 | 9 | window.addEventListener('userproximity', sensorChange, true); -------------------------------------------------------------------------------- /CH08/Listing-8-007.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_8_007 { 2 | const sensorChange = function (reading) { 3 | var proximity = reading.near ? 4 | 'Near' : 'Far'; 5 | alert(proximity); 6 | } 7 | 8 | const readProximity = function () { 9 | const sensor = new ProximitySensor(); 10 | try { 11 | sensor.open(); 12 | 13 | const reading = sensor.read(); 14 | 15 | sensorChange(reading); 16 | } finally { 17 | sensor.close(); 18 | } 19 | } 20 | 21 | window.setInterval(readProximity, 500); 22 | } -------------------------------------------------------------------------------- /CH08/Listing-8-008.ts: -------------------------------------------------------------------------------- 1 | namespace Listing_8_008 { 2 | const sensorChange = function (reading) { 3 | var proximity = reading.near ? 4 | 'Near' : 'Far'; 5 | alert(proximity); 6 | } 7 | 8 | const readProximity = function () { 9 | const sensor = new ProximitySensor(); 10 | 11 | sensor.open() 12 | .then(() => { 13 | return sensor.read(); 14 | }) 15 | .then((reading) => { 16 | sensorChange(reading); 17 | }) 18 | .finally(() => { 19 | sensor.close(); 20 | }); 21 | } 22 | 23 | window.setInterval(readProximity, 500); 24 | } -------------------------------------------------------------------------------- /CH08/Listing-8-009.js: -------------------------------------------------------------------------------- 1 | var CommunicationLines = /** @class */ (function () { 2 | function CommunicationLines() { 3 | } 4 | CommunicationLines.prototype.calculate = function (teamSize) { 5 | return (teamSize * (teamSize - 1)) / 2; 6 | }; 7 | return CommunicationLines; 8 | }()); 9 | function testCommunicationLines() { 10 | var communicationLines = new CommunicationLines(); 11 | var result = communicationLines.calculate(4); 12 | if (result !== 6) { 13 | throw new Error('Test failed for team size of 4.'); 14 | } 15 | result = communicationLines.calculate(10); 16 | if (result !== 45) { 17 | throw new Error('Test failed for team size of 10.'); 18 | } 19 | } 20 | testCommunicationLines(); 21 | -------------------------------------------------------------------------------- /CH08/Listing-8-009.ts: -------------------------------------------------------------------------------- 1 | class CommunicationLines { 2 | calculate(teamSize: number) { 3 | return (teamSize * (teamSize - 1)) / 2 4 | } 5 | } 6 | 7 | function testCommunicationLines() { 8 | const communicationLines = new CommunicationLines(); 9 | 10 | let result = communicationLines.calculate(4); 11 | 12 | if (result !== 6) { 13 | throw new Error('Test failed for team size of 4.'); 14 | } 15 | 16 | result = communicationLines.calculate(10); 17 | 18 | if (result !== 45) { 19 | throw new Error('Test failed for team size of 10.'); 20 | } 21 | } 22 | 23 | testCommunicationLines(); -------------------------------------------------------------------------------- /CH08/Listing-8-011.ts: -------------------------------------------------------------------------------- 1 | import { Performance } from './Listing-8-010'; 2 | 3 | class CommunicationLines { 4 | calculate(teamSize: number) { 5 | return (teamSize * (teamSize - 1)) / 2 6 | } 7 | } 8 | 9 | function testCommunicationLines() { 10 | const communicationLines = new CommunicationLines(); 11 | 12 | let result = communicationLines.calculate(4); 13 | 14 | if (result !== 6) { 15 | throw new Error('Test failed for team size of 4.'); 16 | } 17 | 18 | result = communicationLines.calculate(10); 19 | 20 | if (result !== 45) { 21 | throw new Error('Test failed for team size of 10.'); 22 | } 23 | } 24 | 25 | const result = Performance.run(testCommunicationLines); 26 | 27 | console.log(result.totalRunTime + ' ms'); -------------------------------------------------------------------------------- /CH08/Listing-8-012.ts: -------------------------------------------------------------------------------- 1 | import { Performance } from './Listing-8-010'; 2 | 3 | class CommunicationLines { 4 | calculate(teamSize: number) { 5 | return (teamSize * (teamSize - 1)) / 2 6 | } 7 | } 8 | 9 | function testCommunicationLines() { 10 | const communicationLines = new CommunicationLines(); 11 | 12 | let result = communicationLines.calculate(4); 13 | 14 | if (result !== 7) { 15 | throw new Error('Test failed for team size of 4.'); 16 | } 17 | 18 | result = communicationLines.calculate(10); 19 | 20 | if (result !== 45) { 21 | throw new Error('Test failed for team size of 10.'); 22 | } 23 | } 24 | 25 | const result = Performance.run(testCommunicationLines); 26 | 27 | console.log(result.totalRunTime + ' ms'); -------------------------------------------------------------------------------- /CH08/obj/Debug/Appendix01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH08/obj/Debug/Chapter08.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH08/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH08/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH08/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH09/.vs/Chapter9/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH09/.vs/Chapter9/v15/.suo -------------------------------------------------------------------------------- /CH09/.vs/Chapter9/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH09/.vs/Chapter9/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH09/dist/mynewlib.js: -------------------------------------------------------------------------------- 1 | /// 2 | var NewProcessor = /** @class */ (function () { 3 | function NewProcessor() { 4 | } 5 | NewProcessor.prototype.process = function (name) { 6 | return old_process(name); 7 | }; 8 | return NewProcessor; 9 | }()); 10 | -------------------------------------------------------------------------------- /CH09/dist/myoldlib.js: -------------------------------------------------------------------------------- 1 | function old_process(name) { 2 | return name + ' processed'; 3 | } 4 | -------------------------------------------------------------------------------- /CH09/knockout.d.ts: -------------------------------------------------------------------------------- 1 | interface KnockoutApplyBindings { 2 | (viewModel: {}, rootNode?: HTMLElement): void; 3 | } 4 | 5 | interface Knockout { 6 | applyBindings: KnockoutApplyBindings; 7 | computed: (evaluator: () => any) => any; 8 | observable: (value: any) => any; 9 | observableArray: (value: any[]) => any; 10 | } 11 | 12 | declare var ko: Knockout; -------------------------------------------------------------------------------- /CH09/mynewlib.js: -------------------------------------------------------------------------------- 1 | /// 2 | var NewProcessor = /** @class */ (function () { 3 | function NewProcessor() { 4 | } 5 | NewProcessor.prototype.process = function (name) { 6 | return old_process(name); 7 | }; 8 | return NewProcessor; 9 | }()); 10 | -------------------------------------------------------------------------------- /CH09/mynewlib.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | class NewProcessor { 4 | process(name: string) { 5 | return old_process(name); 6 | } 7 | } -------------------------------------------------------------------------------- /CH09/myoldlib.js: -------------------------------------------------------------------------------- 1 | function old_process(name) { 2 | return name + ' processed'; 3 | } -------------------------------------------------------------------------------- /CH09/obj/Debug/Appendix01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH09/obj/Debug/Chapter9.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH09/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH09/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH09/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH09/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myproject", 3 | "version": "1.0.0", 4 | "devDependencies": { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CH10/.vs/Chapter10/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH10/.vs/Chapter10/v15/.suo -------------------------------------------------------------------------------- /CH10/.vs/Chapter10/v15/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH10/.vs/Chapter10/v15/sqlite3/storage.ide -------------------------------------------------------------------------------- /CH10/FizzBuzz.ts: -------------------------------------------------------------------------------- 1 | export class FizzBuzz { 2 | generate(input: number): string | number { 3 | let output = ''; 4 | 5 | if (input % 3 === 0) { 6 | output += 'Fizz'; 7 | } 8 | 9 | if (input % 5 === 0) { 10 | output += 'Buzz'; 11 | } 12 | 13 | return output === '' ? input : output; 14 | } 15 | } -------------------------------------------------------------------------------- /CH10/obj/Debug/Appendix01.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH10/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | dbfe07a370be37bb2c692a7291f92175868bc5d0 2 | -------------------------------------------------------------------------------- /CH10/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/CH10/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /CH10/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fizzbuzz", 3 | "version": "1.0.0", 4 | "devDependencies": { 5 | "@types/jest": "^21.1.0", 6 | "jest": "^21.1.0" 7 | }, 8 | "scripts": { 9 | "test": "jest" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-typescript-2017/d5468a1d00364469fb6fc8c8228126a60eab9515/LICENSE.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Pro TypeScript*](http://www.apress.com/9781484232484) by Steve Fenton (Apress, 2017). 4 | 5 | [comment]: #cover 6 | 7 | 8 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 9 | 10 | ## Releases 11 | 12 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 13 | 14 | ## Contributions 15 | 16 | See the file Contributing.md for more information on how you can contribute to this repository. 17 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! --------------------------------------------------------------------------------