first commit
This commit is contained in:
commit
80f3a228ca
3 files changed
+348
No files matched your search
+12
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<script type="module" src="script.ts"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Advanced WebDev TypeScript</h1>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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<number> = [1, 2, 3, 4, 5, 500];
|
||||
|
||||
let fruits: Array<string> = ["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<number>): Array<number> {
|
||||
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 <T> slide 25 & 26 ///
|
||||
|
||||
function wrapInArray<T>(item: T): T[] {
|
||||
return [item];
|
||||
}
|
||||
|
||||
const numberArray = wrapInArray(1234);
|
||||
const stringArray = wrapInArray("WebDev");
|
||||
|
||||
//console.log(numberArray)
|
||||
//console.log(stringArray)
|
||||
|
||||
interface ApiResponse<Data> {
|
||||
status: number;
|
||||
success: boolean;
|
||||
payload: Data;
|
||||
}
|
||||
|
||||
interface UserPayload {
|
||||
username: string;
|
||||
}
|
||||
|
||||
const response: ApiResponse<UserPayload> = {
|
||||
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<T> makes all properties in T optional //
|
||||
|
||||
function updateTask(task: Task, fieldsToUpdate: Partial<Task>): 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 <T> //
|
||||
|
||||
type CompleteTask = Required<Task>;
|
||||
|
||||
//16.3 Readonly<T> //
|
||||
|
||||
type ImmutableTask = Readonly<Task>;
|
||||
|
||||
//16.4 Pick<T, K> selects a set of properties K from T
|
||||
type TaskPreview = Pick<Task, "id" | "title">;
|
||||
//Omit<T, K> removes properties K from T
|
||||
type TaskForm = Omit<Task, "id">;
|
||||
|
||||
const preview: TaskPreview = { id: 100, title: "Review Assignment" };
|
||||
|
||||
const formInput: TaskForm = {
|
||||
title: "Release 001",
|
||||
description: "release 001 assignment",
|
||||
completed: false,
|
||||
};
|
||||
|
||||
//16.5 Record<K, T> construct an object map from keys K to values T //
|
||||
|
||||
type UserRole = "admin" | "editor" | "viewer";
|
||||
|
||||
const permission: Record<UserRole, string[]> = {
|
||||
admin: ["read", "write", "delete"],
|
||||
editor: ["read", "write"],
|
||||
viewer: ["read"],
|
||||
};
|
||||
|
||||
// console.log(permission.editor)
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"strict": false
|
||||
},
|
||||
"include": ["**/*"]
|
||||
}
|
||||
Reference in new issue
Block a user