From 80f3a228ca1b537c6266c0b060255453997fadde Mon Sep 17 00:00:00 2001 From: Jeannette Chin Date: Mon, 21 Sep 2026 20:34:38 +0100 Subject: [PATCH] first commit --- index.html | 12 ++ script.ts | 327 ++++++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 9 ++ 3 files changed, 348 insertions(+) create mode 100644 index.html create mode 100644 script.ts create mode 100644 tsconfig.json diff --git a/index.html b/index.html new file mode 100644 index 0000000..09f0bd9 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + Document + + + +

Advanced WebDev TypeScript

+ + diff --git a/script.ts b/script.ts new file mode 100644 index 0000000..47452ce --- /dev/null +++ b/script.ts @@ -0,0 +1,327 @@ +//1. implicit type inference /// + +let language = "Jeannette"; // inferred as string +let year = 2026; //inferred as number + +//console.log(language) + +//1.1. explicit Type annotations - slide 10 /// +let age: number = 100; +let isPresenter: boolean = true; +let emptyValue: null = null; +let notAssigned: undefined = undefined; + +//1.2. type any /// + +let value: any; + +value = 123; // ok +value = "123"; // ok +value = true; // ok + +//1.3. type union - allows a value to be one of several types, defined using the pipe (|) symbol. /// + +type IDD = string | number; + +function printId(id: IDD) { + // Type narrowing with typeof + if (typeof id === "string") { + console.log(`ID string in uppercase: ${id.toUpperCase()}`); + } else { + console.log(`Numeric ID multiplied: ${id * 10}`); + } +} + +//printId(101); // Valid +//printId("task_abc"); // Valid +// printId(true); // Error: Argument of type 'boolean' is not assignable to parameter of type 'string | number'. + +//2. Array - slide 11/// + +let techStack: string[] = ["TS", "JS", "Node", "Next.js"]; + +let scores: Array = [1, 2, 3, 4, 5, 500]; + +let fruits: Array = ["orange", "apple", "berry"]; + +//console.log(techStack) +//console.log(fruits) + +// what is the type of below array? + +let array1 = ["CMP6057A", 6057, true]; + +//let array2: (string | number | boolean)[] = ["CMP6057A", 6057, true] + +//2.1. tuples - fixed-length arrays where each index has a specific type + +let httpStatus: [number, string] = [200, "OK"]; + +//console.log(httpStatus[1]) + +//2.2. objects // + +let object: object; //ok + +object = {}; // ok +object = []; // ok but why? + +let user: { id: number; name: string; isAdmin?: boolean } = { + id: 1, + name: "JC", +}; + +//console.log(user) + +//2.3. Enums : name constants /// + +enum Role { + Admin = "Admin", + User = "User", + Guest = "Guest", +} + +let currentRole = Role.Admin; +//console.log(currentRole) + +//3. Type alias - slide 13 & 14 // + +type ID = string | number; +type OrderStatus = + | "pending" + | "processing" + | "shipped" + | "delivered" + | "cancelled"; + +type Order = { + id: ID; + status: OrderStatus; + totalAmount: number; +}; + +function updateOrderStatus(orderID: ID, newStatus: OrderStatus): void { + console.log(`order ${orderID} moved to status ${newStatus}`); +} + +//updateOrderStatus("order 12344", "shipped"); +//updateOrderStatus("order 9999", "refunded"); + +/// slides for complex examples slide 15 - 17 // + +///3.1. interface - slide 18 /// + +interface Vehicle { + make: string; + model: string; +} + +interface Car extends Vehicle { + isElectric: boolean; +} + +const tesla: Car = { + make: "Tesla", + model: "Model 3", + isElectric: true, +}; + +//console.log(tesla); + +//3.2. index signature - slide 19 // +interface OrderObj { + Banana: number; + Sugar: number; + Potato: number; + Egg: number; + Milk: number; +} + +const myOrders: OrderObj = { + Banana: 3, + Sugar: 1, + Potato: 2, + Egg: 6, + Milk: 1, +}; + +//console.log(myOrders.Egg); //6 + +// const totalOrder = (orders:OrderObj):number => { +// let total = 0; +// for (const order in orders) { +// total += orders[order] +// } + +// return total +// } + +// console.log(totalOrder(myOrders)) + +///12. rest parameters - allows a function to accept any number of arguments as an array , TS ensures every passed argument matches the declared array element type - slide 20 /// + +function multiply(factor: number, ...numbers: Array): Array { + return numbers.map((n) => n * factor); +} + +//console.log(multiply(2, 1,3,5,7)) // 2,6,10,14 + +/// more examples // +type UserLoginArgs = [userID: number, timestamp: Date]; +type SystemErrorArgs = [errorCode: number, message: string, isFatal: boolean]; + +function logUserLogin(...args: UserLoginArgs): void { + const [userID, timestamp] = args; + console.log(`User ${userID} logged in at ${timestamp.toISOString()}`); +} + +//logUserLogin(1234, new Date()) + +function logSystemError(...args: SystemErrorArgs): void { + const [code, message, fatal] = args; + console.log(`Error ${code}, ${message} | Fatal: ${fatal}`); +} + +//logSystemError(500, "DB Error", true); + +///13. Type Never : A function has the return type never if it either always throws an error or never terminates. slide 22 & 23 /// + +// Always throws an exception +function fail(message: string): never { + throw new Error(message); +} + +// Runs an infinite loop +function runForever(): never { + while (true) { + // Background polling, daemon loop, etc. + } +} + +///Exhaustive Type Checking (default Cases) +// The most common real-world use of never is ensuring that all members of a union are handled at compile time. + +type Shape = + | { kind: "circle"; radius: number } + | { kind: "square"; side: number }; + +function getArea(shape: Shape): number { + switch (shape.kind) { + case "circle": + return Math.PI * shape.radius ** 2; + case "square": + return shape.side * shape.side; + default: { + // If all cases are handled, `shape` is narrowed down to `never`. + const _exhaustiveCheck: never = shape; + throw new Error(`Unhandled shape: ${_exhaustiveCheck}`); + } + } +} + +//If you later add { kind: "triangle" } to Shape without updating the switch statement, TypeScript will flag a compile-time error: Type 'Triangle' is not assignable to type 'never'. // + +///14. Assertion "as" slide 24 // + +// Example with unknown (e.g., from an external API or JSON.parse) +const rawData: unknown = "advanced WebDev 001 assessment"; + +// Without assertion, rawData.length throws an error: Object is of type 'unknown' +const titleLength = (rawData as string).length; +//console.log(titleLength); // 30 + +// document.getElementById returns HTMLElement | null +// HTMLInputElement gives access to .value, .checked, etc. +const inputElement = document.getElementById( + "username-input", +) as HTMLInputElement; + +//console.log(inputElement.value); // Valid: value exists on HTMLInputElement + +///15. Generics slide 25 & 26 /// + +function wrapInArray(item: T): T[] { + return [item]; +} + +const numberArray = wrapInArray(1234); +const stringArray = wrapInArray("WebDev"); + +//console.log(numberArray) +//console.log(stringArray) + +interface ApiResponse { + status: number; + success: boolean; + payload: Data; +} + +interface UserPayload { + username: string; +} + +const response: ApiResponse = { + status: 200, + success: true, + payload: { username: "JC" }, +}; + +//console.log(response.payload); + +///16. utility slide26// + +interface Task { + id: number; + title: string; + description: string; + completed: boolean; +} + +//16.1 Partial makes all properties in T optional // + +function updateTask(task: Task, fieldsToUpdate: Partial): Task { + return { ...task, ...fieldsToUpdate }; +} + +const myTask = { + id: 123, + title: "001 assignment", + description: "advanced WebDev 001 assessment", + completed: false, +}; + +//updateTask(myTask, {completed:true}) +//console.log(myTask) // complete = false , why? + +//16.2 Required // + +type CompleteTask = Required; + +//16.3 Readonly // + +type ImmutableTask = Readonly; + +//16.4 Pick selects a set of properties K from T +type TaskPreview = Pick; +//Omit removes properties K from T +type TaskForm = Omit; + +const preview: TaskPreview = { id: 100, title: "Review Assignment" }; + +const formInput: TaskForm = { + title: "Release 001", + description: "release 001 assignment", + completed: false, +}; + +//16.5 Record construct an object map from keys K to values T // + +type UserRole = "admin" | "editor" | "viewer"; + +const permission: Record = { + admin: ["read", "write", "delete"], + editor: ["read", "write"], + viewer: ["read"], +}; + +// console.log(permission.editor) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c47cee4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "strict": false + }, + "include": ["**/*"] +}