├── .eslintrc ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── README.md ├── package.json ├── public └── index.html ├── src ├── @types │ └── question.d.ts ├── client │ ├── README.md │ ├── client.ts │ └── tsconfig.json └── server │ ├── README.md │ ├── server.ts │ └── tsconfig.json ├── tsconfig-base.json └── tsconfig.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "plugin:@typescript-eslint/recommended" 5 | ], 6 | "rules": { 7 | "@typescript-eslint/type-annotation-spacing" : [1, { 8 | "before" : true, 9 | "after" : true 10 | }] 11 | } 12 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | *.txt 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | .vs 24 | 25 | bin 26 | 27 | notes.md 28 | 29 | obj 30 | 31 | archive 32 | 33 | *.njsproj 34 | *.njsproj.user 35 | *.sln 36 | *.map 37 | *.js 38 | !legacy/*.js 39 | 40 | notes.md 41 | 42 | # Coverage directory used by tools like istanbul 43 | coverage 44 | *.lcov 45 | 46 | # nyc test coverage 47 | .nyc_output 48 | 49 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 50 | .grunt 51 | 52 | # Bower dependency directory (https://bower.io/) 53 | bower_components 54 | 55 | # node-waf configuration 56 | .lock-wscript 57 | 58 | # Compiled binary addons (https://nodejs.org/api/addons.html) 59 | build/Release 60 | 61 | # Dependency directories 62 | node_modules/ 63 | jspm_packages/ 64 | 65 | # TypeScript v1 declaration files 66 | typings/ 67 | 68 | # TypeScript cache 69 | *.tsbuildinfo 70 | 71 | # Optional npm cache directory 72 | .npm 73 | 74 | # Optional eslint cache 75 | .eslintcache 76 | 77 | # Microbundle cache 78 | .rpt2_cache/ 79 | .rts2_cache_cjs/ 80 | .rts2_cache_es/ 81 | .rts2_cache_umd/ 82 | 83 | # Optional REPL history 84 | .node_repl_history 85 | 86 | # Output of 'npm pack' 87 | *.tgz 88 | 89 | # Yarn Integrity file 90 | .yarn-integrity 91 | 92 | # dotenv environment variables file 93 | .env 94 | .env.test 95 | 96 | # parcel-bundler cache (https://parceljs.org/) 97 | .cache 98 | 99 | # next.js build output 100 | .next 101 | 102 | # nuxt.js build output 103 | .nuxt 104 | 105 | # gatsby files 106 | .cache/ 107 | # public 108 | build 109 | 110 | # vuepress build output 111 | .vuepress/dist 112 | 113 | # Serverless directories 114 | .serverless/ 115 | 116 | # FuseBox cache 117 | .fusebox/ 118 | 119 | # DynamoDB Local files 120 | .dynamodb/ 121 | 122 | # TernJS port file 123 | .tern-port 124 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch via NPM", 11 | "runtimeExecutable": "npm", 12 | "runtimeArgs": [ 13 | "run-script", 14 | "debug" 15 | ], 16 | "port": 9227, 17 | "sourceMaps": true 18 | } , 19 | { 20 | "type": "chrome", 21 | "request": "launch", 22 | "name": "Launch Chrome", 23 | "url": "http://localhost:1337", 24 | "webRoot": "${workspaceFolder}" 25 | }, 26 | ], 27 | "compounds": [ 28 | { 29 | "name": "Run and Debug", 30 | "configurations": ["Launch via NPM", "Launch Chrome"] 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | // Note - could the matching of this tsconfig be what is causing .watch tasks to output to the wrong directory? 5 | "version": "2.0.0", 6 | "tasks": [ 7 | { 8 | "type": "typescript", 9 | "tsconfig": "tsconfig.json", 10 | "problemMatcher": [ 11 | "$tsc" 12 | ], 13 | "group": { 14 | "kind": "build", 15 | "isDefault": true 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Compiling TypeScript 2 | 3 | ## Installing and Running the Completed Package 4 | 5 | 1. OPTIONAL - Install the TypeScript compiler globally (local install is also possible): 6 | `npm install -g typescript` 7 | 8 | 2. Install this package with Git: 9 | `git clone git@github.com:danielstern/compiling-typescript.git` 10 | 11 | 3. Install local packages with `npm`: 12 | `npm install` 13 | 14 | 4. Run TypeScript compilation and start the server simultaneously with: 15 | `npm start` 16 | 17 | ## Exploring the Project 18 | 19 | ### /public 20 | Contains HTML file which is served to the user - aggregates references to generated .js files. 21 | 22 | ### /src 23 | Contains the non-compiled TypeScript code. This code becomes JavaScript that the browser can work with. 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compiling-type-script2", 3 | "version": "0.0.0", 4 | "description": "CompilingTypeScript2", 5 | "main": "server.js", 6 | "author": { 7 | "name": "Daniel 'Code Whisperer' Stern" 8 | }, 9 | "scripts": { 10 | "build-full": "tsc --build", 11 | "build-server": "tsc -p src/server", 12 | "build-client": "tsc -p src/client", 13 | "watch-client": "tsc -p src/client --watch", 14 | "build": "tsc -p tsconfig.json", 15 | "serve": "node build/server/server.js", 16 | "start": "npm run build-full && npm run serve", 17 | "debug": "node --inspect=9227 build/server/server.js", 18 | "lint": "eslint src/**/*.ts" 19 | }, 20 | "devDependencies": { 21 | "@types/express": "^4.17.1", 22 | "@types/node": "^8.10.58", 23 | "@typescript-eslint/eslint-plugin": "^2.7.0", 24 | "@typescript-eslint/parser": "^2.7.0", 25 | "eslint": "^6.6.0", 26 | "express": "^4.17.1", 27 | "typescript": "^3.2.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | Educational Resources Access 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 |
17 | Educational Resources Access 18 |
19 | 23 | Sign up 24 |
25 | 26 |
27 | 28 | 29 |
30 | 31 | 32 |
33 | 34 |

Ask a Question

35 | 36 |
37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | Valid title is required. 45 | 46 |
47 | 48 |
49 | 50 |
51 | 52 | 53 | 54 | 55 | 56 |
57 | 58 | 59 | 60 |
61 | 62 |
63 | 64 | 65 | 66 |
67 | 68 |

69 | 70 | New Questions 71 | 72 | 2 73 | 74 |

75 | 76 | 81 | 82 |
83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/@types/question.d.ts: -------------------------------------------------------------------------------- 1 | export interface Question { 2 | title : string; 3 | content : string; 4 | answerCount ? : number; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/client/README.md: -------------------------------------------------------------------------------- 1 | # Client 2 | 3 | ## About 4 | The Client communicates with the server and updates the view that the user sees. It is the user-facing code, which is loaded by Chrome. 5 | 6 | ### Functionality 7 | Provides a simple form and list. Submitting the form communicates with the server (`./../server/server.ts`), gets updated server state, and renders. -------------------------------------------------------------------------------- /src/client/client.ts: -------------------------------------------------------------------------------- 1 | import { Question } from '../@types/question'; 2 | 3 | (() : void => { 4 | 5 | let questions : Question[] = []; 6 | 7 | function render () : void { 8 | 9 | document.getElementById("Questions").innerHTML = questions.map(({title, content, answerCount = 0}) => ` 10 |
  • 11 | 12 |
    13 | 14 |
    15 | 16 | ${title} 17 | 18 |
    19 | 20 | 21 | 22 | ${content} 23 | 24 | 25 | 26 |
    27 | 28 | 29 | 30 | ${answerCount} Answer${answerCount === 0 || answerCount > 1 ? `s` : ``} 31 | 32 | 33 |
  • 34 | `).join(""); 35 | } 36 | 37 | (async function init() : Promise { 38 | 39 | const request = await fetch("/questions"); 40 | questions = await request.json(); 41 | /* debugger; */ 42 | /* Remove comment to trigger breakpoint */ 43 | render(); 44 | 45 | })(); 46 | 47 | 48 | async function handleSubmitQuestionForm () : Promise { 49 | 50 | event.preventDefault(); 51 | 52 | const title : string = document.forms["QuestionForm"][0].value; 53 | const content : string = document.forms["QuestionForm"][1].value; 54 | 55 | const request = await fetch(`/new?title=${title}&content=${content}`); 56 | const json = await request.json(); 57 | 58 | questions = json.questions; 59 | render(); 60 | 61 | } 62 | 63 | document.getElementById('QuestionForm').addEventListener("submit", handleSubmitQuestionForm); 64 | 65 | })(); -------------------------------------------------------------------------------- /src/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "composite": true, 5 | "outDir": "../../build/client", 6 | "tsBuildInfoFile": "../../build/cache/client/.tsbuildinfo", 7 | "module": "es6", 8 | "target": "es5", 9 | "baseUrl": "./", 10 | "paths": { 11 | "*" : ["src/@types/*"] 12 | }, 13 | "strictNullChecks": false, 14 | "lib": [ 15 | "es5", 16 | "dom" 17 | ] 18 | }, 19 | } -------------------------------------------------------------------------------- /src/server/README.md: -------------------------------------------------------------------------------- 1 | # Server 2 | 3 | ## About 4 | The server is the back-end component of the application which is never served to the user. It validates information and serves HTML and JavaScript files to the end user. 5 | 6 | ### Functionality 7 | The server sends relevant files to browsers accessing the app at the relevant port (`1337` by default). The server also contains a simple REST API that retrieves and adds new questions. -------------------------------------------------------------------------------- /src/server/server.ts: -------------------------------------------------------------------------------- 1 | /** @types/express must be installed in this project for VSCode to provide the correct code hints for the file below */ 2 | 3 | import * as express from "express"; 4 | import * as path from "path"; 5 | import { Question } from '../@types/question'; 6 | 7 | /*import { Question } from '../shared/Question';*/ 8 | 9 | const port : string | number = process.env.port || 1337; 10 | const app = express(); 11 | 12 | const questions : Question[] = [{ 13 | title: "Are dividends tax deductible?", 14 | content: "I have recently decided to invest in....", 15 | answerCount: 2 16 | },{ 17 | title:"Is it smart to invest in commodities?", 18 | content:"My bank has recently offered a new....", 19 | answerCount: 1 20 | }]; 21 | 22 | app.use(express.static("public")); 23 | 24 | app.get("/main.js", (_req, res) => { 25 | 26 | /** This patch is relative to the build directory */ 27 | res.sendFile(path.resolve(__dirname, "..", "client", "client.js")); 28 | 29 | }); 30 | 31 | /* 32 | app.get("/client.js.map", (_req, res) => { 33 | 34 | res.sendFile(path.resolve(__dirname, "..", "client", "client.js.map")); 35 | 36 | }); 37 | 38 | app.get("/src/client/client.ts", (_req, res) => { 39 | 40 | res.sendFile(path.resolve(__dirname, "..", "..", "src", "client", "client.ts")); 41 | 42 | }); 43 | failed attempt to get source files working via serving... attempting to inline instead */ 44 | 45 | app.get("/questions", (_req, res) => { 46 | 47 | res.json(questions); 48 | 49 | }); 50 | 51 | app.get("/new", (req, res) => { 52 | 53 | const question : Question = req.query; 54 | questions.push(question); 55 | 56 | res.json({ 57 | 58 | status: "OK", 59 | questions 60 | 61 | }) 62 | 63 | }); 64 | 65 | app.listen(port); 66 | console.info(`App listening on port ${port}!`); -------------------------------------------------------------------------------- /src/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "composite": true, 5 | "outDir": "../../build/server", 6 | "tsBuildInfoFile": "../../build/cache/server/.tsbuildinfo", 7 | "module": "commonjs", 8 | "target": "es5", 9 | "lib": [ 10 | "es5" 11 | ], 12 | "types": [ 13 | "node" 14 | ], 15 | "typeRoots": [ 16 | "../@types" 17 | ], 18 | "baseUrl": "./", 19 | "paths": { 20 | "*" : ["src/@types/*"] 21 | }, 22 | }, 23 | "files":[ 24 | "server.ts", 25 | "../@types/question.d.ts", 26 | ] 27 | } -------------------------------------------------------------------------------- /tsconfig-base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, // Governs the creation of d.ts files, 4 | "strict": true, 5 | "noUnusedLocals": false, // Declaring a local and not using it will cause a compilation error 6 | "noUnusedParameters": true, 7 | "noImplicitReturns": true, 8 | "noFallthroughCasesInSwitch": true, 9 | "inlineSourceMap": true, 10 | "inlineSources": true, 11 | "noImplicitAny": false, 12 | "watch": true, 13 | "strictNullChecks": false, 14 | "listEmittedFiles":true, 15 | "listFiles":true, 16 | "incremental": true, 17 | "tsBuildInfoFile": "./build/cache/.tsbuildinfo" 18 | } 19 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig-base.json", 3 | "references": [ 4 | { 5 | "path": "./src/server" 6 | }, 7 | { 8 | "path": "./src/client" 9 | } 10 | 11 | ], 12 | "compilerOptions": { 13 | "declaration": true, 14 | "target": "es6", 15 | "lib": [ 16 | "es6", 17 | "dom" 18 | ], 19 | "rootDir": "./src", 20 | "outDir": "./build", 21 | }, 22 | "files": [ 23 | /* Empty files array specifies that no files should be compiled directly as part of this master package */ 24 | ] 25 | } --------------------------------------------------------------------------------