Understanding TypeScript Basics
Understanding TypeScript Basics
pages interactive and dynamic instead of just static. A static page shows the
same content to everyone and doesn’t change unless a developer updates it,
like a simple HTML page. A dynamic page changes its content based on user
actions, data, or other conditions, like a Facebook feed or a shopping cart. In
the browser, Java script can change HTML, update design, store data, and
make HTTP requests using the V8 engine, while on the server with [Link] it
can handle requests, store data in databases, and connect with APIs like GPT.
In normal raw code, we keep HTML, CSS, and JS separate to increase
readability, modularity, and caching efficiency, and when multiple websites
have different CSS and JS, each HTML file links to its respective style and
script files.
One major drawback of plain Java script is that it is dynamically typed,
meaning you can assign any type of value to a variable without checks, which
can cause bugs in bigger projects. To solve this, we have TypeScript, which
includes all Typescript features plus extra features and type safety. Type
safety means you can define types for variables, functions, and objects, so
assigning a wrong type gives an error. For example, let a: string = "hello"; ensures a
is always a string, and a = 123; will throw an error. Extra features mean
TypeScript provides powerful tools that would take a lot of time if written in
plain Typescript and also includes all Typescript concepts, so you can do
everything Typescript can do in the browser, manipulate HTML, update styles,
store data, and make HTTP requests, and on the server with [Link], handle
requests, work with databases, and connect to APIs like ChatGPT. This works
because TypeScript is converted into Typescript, which the browser and
[Link] can understand and execute properly.
First way: Use an external .ts file. You write your TypeScript code in that file,
then convert it to Typescript using the TypeScript compiler. After that, you add
Typescript Development 2
the converted .js file to your HTML page using a <script src="..."></script> tag. This
is the right and practical way for real projects.
Second way: Use internal TypeScript directly inside a <script> tag in your
HTML. For this, you need a special loader & compiler because browser don’t
understand Typescript, It can work for small experiments, but strictly don’t
use it for real apps because it is slow, messy, and not maintainable.
Scope
Scope tells us where a variable can be accessed or where not, Where you
declare a variable decides its scope: if a variable is declared inside a function,
it has Function Scope (or Local Scope); if it’s declared inside a block {} like a
loop or if‑statement, it has Block Scope; and if it’s declared outside any
function or block, It has Global Scope, and remember, only const and let
follow these rules; var is always treated as global scope.
Always remember if you write something like function test() { potato = true; } test();
[Link](potato); without using var , let , or const , Typescript will automatically
make potato a global variable, even though it was written inside a function. This
is bad practice, because it can create unwanted global values and cause bugs
later.
Hoisting
Typescript Development 3
Hoisting in Typescript means before the code runs, Typescript first reads and
moves all declarations like var , let , const , function , class , and import to the top of
their scope. Because of this, sometimes you can use a variable or function
before it’s written. But only normal function declarations work fully before
writing. var is hoisted but gets the value undefined , so no error, but no real value.
let and const are hoisted but not ready to use, so using them early gives a
Comments
Comments are used to take notes inside the code, and they are not executed
by the compiler.
Data Types
In Typescript there are 7 primitive data types like Number, String, Boolean,
Null, Undefined, BigInt, and Symbol, but we can store arrays, objects, DOM
elements, and functions inside variable too.
Primitives values stored and access directly in memory box and are
immutable.
Primitive values are stored directly inside a box defined by let or const and
can be accessed directly from that box, they are immutable, so their value
Typescript Development 4
cannot be changed once stored, but for let it can be update but for const it
can’t even update.
Non-primitives data types are data structures that are used to store more than
one value. We have built-in data structures that use object types, and we can
also create custom data structures, In Typescript, objects, arrays, and
functions are stored in memory, and the variable you make does not store the
actual value; it stores the reference (address) of that memory box. For arrays
(indexed collection), the reference points to the first box (index 0), and then
Typescript uses that to find the other values. For objects (keyed collection),
each value is stored in memory too, but instead of using numbers like index 0,
we use keys (like name, age) to find the value. Functions are also stored in
memory blocks, and the variable stores the reference to that block. So,
everything is stored by reference, but the way we access it depends on the
type: arrays use numbers (indexes), objects use keys, and functions are
called through their variable reference.
graph TD
A[Data Types & Data Structures]
Typescript Development 5
C1a --> C1a0[Number, String, Boolean]
Typescript Development 6
let age = 25; // stores a number
3. A Boolean is a data type that can have only two options: true or false.
A Symbol is a special data type in Typescript that creates a unique and hidden
key. When we create a symbol, like let id = Symbol("userId") , the text "userId" is just a
description or label to help us identify it; it is not the actual value of the symbol.
The real symbol value is stored in the variable id . When we use it in an object,
for example let user = { name: "Ali" }; user[id] = 101; , the symbol ( id ) acts as a hidden key,
and the value 101 is stored under that key. This key doesn’t appear when you
print the object, but you can still access it using the same symbol. We can use
[Link] to see the text label we gave to the symbol
Use unknown when you don’t know the value yet. You can assign anything, but
before using it, you must check the type, like let value: unknown = 5; if (typeof value ===
"number") { [Link](value + 1); } . Use any when the value can be anything and
TypeScript won’t check it, like let anything: any = "hello"; [Link](anything + 10); .
Typescript Development 7
BigInt is used for very large numbers that normal numbers can’t handle, like let
yet or nothing found, like let user: string | null = null; remember null means a variable
has no value, while 0 is a number, Use undefined when a variable is declared
but not assigned, like let age: number; [Link](age); // undefined . Use void for a
function that does not return anything, like function logMessage(): void { [Link]("Hi");
} . Use never for a function that will never return normally, either because it
throws an error or runs forever, for example function fail(): never { throw new Error("Oops");
} or function infiniteLoop(): never { while(true) {} } . After a never function runs, the code
after it does not execute, You cannot use never with a normal variable,
because it means no value can exist.
and methods. You can create multiple objects using the new keyword, and
Typescript Development 8
classes can include constructors and default logic. Example: class Person { name:
string; constructor(name: string) { [Link] = name; } greet() { [Link]("Hello " + [Link]); } } let p = new
Person("Ali"); [Link]();
// Interface
interface User {
name: string;
age: number;
greet(): void;
}
greet() {
[Link]("Hello " + [Link]);
}
}
Typescript Development 9
Built in
Primitive data types Number, String, and Boolean are auto boxed in Typescript
to create temporary objects, which allows you to use their properties and
methods.
Number Properties
Number Methods
Use toString() to convert number to string, toFixed(n) to round to n decimals,
for n total digits, toExponential(n) for scientific form, valueOf() to get
toPrecision(n)
Typescript Development 10
To make a string from number codes, use [Link]() for normal
codes, and [Link]() for full Unicode codes.
endsWith() to check beginning or end. Use search() for pattern search. Use
Boolean Methods
Boolean values are very simple in Typescript. To get the actual true or false
value from a Boolean object, you can use valueOf() , which returns either true
or false . If you want to convert a Boolean into a string, you can use toString() ,
which returns "true" or "false" . Booleans do not have any built-in properties,
so these two methods are all you need to work with them.
2: Keyed Collection
Build in Keyed Collections
Typescript Development 11
Typescript’s built-in keyed collections like Math, Date, and Error are special
objects with predefined methods and properties. Math does number
operations, like [Link](4.6) ; Date handles date and time, like let now = new Date(); ;
Error creates or handles errors, like throw new Error("Something went wrong"); here, new
creates the error object, and throw stops the program immediately. We cannot
store throw new Error() in a variable because it jumps out of the function or block
and the code after it never runs.
Use Math properties like [Link] to get π and Math.E to get Euler’s number. Use
Math methods to do number operations: [Link](4.6) to round a number,
[Link](4.9) for lower integer, [Link](4.1) for higher integer, [Link](16) for
square root, [Link](2,3) for power, [Link]() for random number between 0–
1, [Link](1,5,3) to get maximum, and [Link](1,5,3) to get minimum.
Use Date methods to work with date and time: let date = new Date() creates current
date, [Link]() to get year, [Link]() to get month (0–11), [Link]() to
get day of month, [Link]() to get day of week (0–6), [Link](2025) to set
year, [Link](10) to set month, and [Link](15) to set day and date don’t
have properties
Use Error properties like [Link] to get the message, [Link] to get the
type, and [Link] to see stack trace. Use throw to stop the program when
something goes wrong, for example throw new Error("Oops")
let id = Symbol("userId"); user[id] = 101; . Void and never cannot be stored in objects
because void is for functions that don’t return anything, and never is for
functions that never return and also we can store arrays, objects, DOM
elements, and functions inside an object variable, We can access, modify,
delete, and add data in them, normally we define object using const but you
can use let also, We can access a key in two ways: using the dot notation
( [Link] ) or by passing the key inside square brackets ( object["key"] )
Typescript Development 12
How to make methods inside Object
In Typescript, we can make a function inside an object in three simple ways.
First, by using the old way with the function keyword like greet: function() {
[Link]("Hello " + [Link]); } it works fine but looks a bit long. Second, by using
the shorthand method like greet() { [Link]("Hi " + [Link]); } — this is short, clean,
and mostly used in modern Typescript or inside classes. Third, by using an
arrow function like greet: () => { [Link]("Hey " + [Link]); } it’s short too but doesn’t
have its own this , so it’s not good when you need to use object values.
We can’t connect one object directly to more than one prototype because the
last [Link] assignment overwrites the previous one. But by linking
them one after another in a prototype chain, we can still access all data step
by step.
Example:
let obj1 = { a: 10 };
let obj2 = { b: 20 };
let obj3 = { c: 30 };
Typescript Development 13
[Link](obj3.a, obj3.b, obj3.c); // 10 20 30
[Link] . To see the main template all objects inherit from, use
Keywords: Keywords are special words associated with a data type. Here,
they are associated with objects, so they are called object keywords.
To delete a property from an object, use delete . To check if a key exists in
an object, use in . To refer to the current object inside a method, use this .
To create a new object from a constructor or class, use new . To define a
Typescript Development 14
blueprint for objects, use class . To inherit from another class, use extends .
To call parent class constructor or methods, use super .
const user = {
name: 'Ali',
age: 30
};
// Increment age by 31
[Link] = [Link] + 31; // ✅ valid
[Link](user);
// Output: { name: 'Ali', age: 62, city: 'Lahore' }
Delete a Value
delete [Link];
[Link](user);
Typescript Development 15
// { name: 'Ali', city: 'Lahore' }
Now let’s rebuild user with all properties for the next examples:
const user = {
name: 'Ali',
age: 30,
city: 'Lahore'
};
[Link]()
[Link]()
[Link]()
Gives an array of key–value pairs, each pair inside its own array.
[Link]()
Typescript Development 16
const details = { country: 'Pakistan' };
const fullUser = [Link](user, details);
[Link](fullUser);
// { name: 'Ali', age: 30, city: 'Lahore', country: 'Pakistan' }
[Link]()
[Link]([Link]('name')); // true
[Link]([Link]('email')); // false
Indexed Collections
Custom Indexed Collections
Normal Array
Typescript Development 17
map()
Use this method when you want to creates a new array by performing a
function on each item of an existing array.
[Link](doubledNumbers);
// Output: [2, 4, 6]
filter()
Use this method when you want to creates a new array that only includes
items that pass a specific test.
[Link](adults);
// Output: [18, 25]
forEach()
Use this method when you want to runs a function for each item in an
array. It does not create a new array.
[Link](name => {
[Link]('Hello, ' + name);
});
// Output:
// Hello, Ali
Typescript Development 18
// Hello, Usman
// Hello, Sara
[Link]('orange');
[Link](fruits);
// Output: ['apple', 'banana', 'orange']
[Link]();
[Link](fruits);
// Output: ['apple', 'banana']
reduce()
Use this method when you want to combine all items into a single value.
You give it a function with two arguments: the accumulator ( sum ) and the
current item ( n ), and the starting value for sum is written after the comma
at the end of reduce() .
Here 0 after the comma is the initial value for sum . If you skip it, reduce will
take the first array element as the starting value automatically. You use
Typescript Development 19
to calculate totals, counts, or merge arrays, like a shopping cart
reduce()
sort()
Use sort() when you want to arrange the items of an array in order
find
Use find() when you want to get the first item that matches a condition.
Sort Method
is a method in Typescript which is used to sort array values in
.sort()
ascending order. For text (words), it looks at the first letter of each word
and sorts alphabetically (A to Z), so ["apple","banana","car"] stays
["apple","banana","car"] . For numbers, if you don’t use a compare function,
Typescript Development 20
values at a time until the whole array is sorted, so if the array has 9 values,
it keeps pairing and comparing until even the last value is in the correct
place.
Extra
If you want to get a new array without changing the original, use
methods like concat() to combine arrays, slice() to take part of an array,
filter() to keep only some elements, map() to change each element, flat()
to flatten nested arrays, flatMap() to flatten and map at the same time,
toReversed() to reverse without changing the original, toSorted() to sort
If you want to modify the original array directly, use copyWithin() to copy
part of the array inside itself, fill() to fill all or part of the array with a
value, pop() to remove the last element, push() to add elements at the
end, reverse() to reverse the array, shift() to remove the first element,
to sort elements in place, splice() to add or remove elements
sort()
If you want to get a single value or information from the array, use at()
to get an element at a specific index, every() to check if all elements
pass a test, find() to get the first matching element, findIndex() to get the
index of the first match, findLast() to get the last matching element,
findLastIndex() to get the index of the last match, includes() to check if the
array has a value, indexOf() to get the index of a value, lastIndexOf() to get
the last index of a value, reduce() to combine all elements into one value,
reduceRight() to combine from right to left, some() to check if any element
If you want to loop over the array or get iterators, use forEach() to run a
function for each element, entries() to get an iterator of [index, value]
pairs, keys() to get an iterator of indexes, and values() to get an iterator of
values. forEach() mainly produces a side effect like printing or updating
something outside, and it does not return anything. The other three
Typescript Development 21
methods give iterators that let you look at elements or indexes step by
step without changing the array.
1. Numbers
You can create an array of numbers like [1, 2, 3, 100, -50] . Use it when you
want to store multiple numeric values together.
2. Strings
You can create an array of strings like ["apple", "banana", "hello"] . Use it when you
want to store multiple text values.
3. Booleans
You can create an array of booleans like [true, false, true] . Use it when you
want to store multiple yes/no or true/false values.
4. Null
You can create an array containing null values like [null, null, null] . Use it when
you want placeholders or empty values in your array.
5. Undefined
You can create an array with undefined values like [undefined, undefined] . Use it
when values are not assigned yet.
6. BigInts
You can create an array of bigints like [10n, 9007199254740991n] . Use it when you
want to store very large integers safely.
7. Objects
You can create an array of objects like [{name:"Ali"}, {age:25}] . Use it when you
want to store structured data with keys and values.
8. Functions
You can create an array of functions like [function(){}, () => [Link]("Hi")] . Use it
when you want to call multiple functions dynamically from the array.
9. Arrays
Typescript Development 22
You can create an array of arrays (nested arrays) like [[1,2],[3,4]] . Use it for
multi-dimensional data, like matrices or grouped values.
10. DOM Elements
You can create an array of DOM elements like [[Link], [Link],
Typed Array
Typed arrays are special arrays that store only numbers of a specific type
efficiently. Int8Array stores 8-bit signed integers (-128 to 127), Uint8Array
stores 8-bit unsigned integers (0–255), Uint8ClampedArray stores 8-bit
clamped integers (0–255, useful for colors), Int16Array stores 16-bit signed
integers (-32,768 to 32,767), Uint16Array stores 16-bit unsigned integers (0–
65,535), Int32Array stores 32-bit signed integers (-2,147,483,648 to
2,147,483,647), Uint32Array stores 32-bit unsigned integers (0–
4,294,967,295), Float32Array stores 32-bit floating point numbers, and
Float64Array stores 64-bit floating point numbers. Each typed array can hold
as many elements as memory allows, but each element must stay within the
type’s allowed range. For example: let temps = new Int8Array([-5, 0, 12, -20]);
[Link](temps); → Int8Array [-5, 0, 12, -20] . In short: use typed arrays when you want
Tuple
A tuple is like an array but stricter because it has a fixed length and fixed
types in a specific order. You define the type of each element when you
create it, and you must follow that order exactly. For example, [string, number,
boolean] can store a username, age, and active flag. If you try to put extra
elements or change the order, TypeScript will give an error. Unlike arrays,
which are flexible and can store any number of values of the same or different
types, tuples are for cases where you want specific types in a specific order.
Example: let user: [string, number, boolean]; user = ["Ali", 25, true]; Correct, but ["Ali", true, 25]
Typescript Development 23
Wrong. If you want many values of the same type, use a regular array instead,
like let users: string[] = ["Ali", "Ali", "Ali"];
Destructuring
Destructuring is just a shortcut to use object or array values by directly storing
them inside local variables, and remember for arrays because they don’t have
keys, the variable names can be anything, but for objects you need to use the
exact key names unless you want to rename like key: variable . Also, for arrays,
local variables store values based on their index, so if you want to skip
something you just use a comma , for objects, you can’t “skip” values like
arrays because objects don’t have order or indexes they have keys. If you don’t
want a certain key, you just don’t include it in your destructuring
The rest operator ... works for both: for arrays it stores the remaining values in
a new array, and for objects it stores the remaining keys in a new object. For
example, const person = { name: "Ali", age: 20, city: "Lahore", country: "Pakistan" }; const { name, age, city:
shehar, ...rest } = person; [Link](name, age, shehar, rest); prints Ali 20 Lahore { country: "Pakistan" } .
For arrays, const arr = [10, 20, 30, 40]; const [first,,third, ...others] = arr; [Link](first, third, others);
prints 10 30 [40] .
Key Of Operator
keyof operator in TypeScript gives you all the property names of an object or
interface as a type. For example, if interface User { name: string; age: number; location: string } ,
then type UserKeys = keyof User becomes "name" | "age" | "location" , and you can use any
of these keys like const key: UserKeys = "name" , but not a key that doesn’t exist.
Operators
Operators are used to performs operations on values.
Operator Precedence
Operator Precedence is used to know the order in which operators will be
performed in an expression, like the order of operations in math. Operators
with higher precedence are evaluated first.
Typescript Development 24
For example, in 2 + 3 * 4 , the multiplication ( * ) is done first because it has a
higher precedence than addition ( + ). The expression becomes 2 + 12 , which
equals 14 .
Operator Associativity
Associativity is used to determines the direction in which operators will
executed in an expression when they have the same precedence. It can be
either left-to-right or right-to-left.
For example, in a-b+c , subtraction and addition have the same precedence.
Their associativity is left-to-right, so the expression is evaluated as (a - b) + c .
Most operators are left-to-right, but some, like the assignment operators, are
right-to-left. For example, a = b = 10 is evaluated from right to left, meaning b is
assigned 10 first, and then a is assigned the value of b .
Operators
Arithmetic Operators
Arithmetic operators are used to perform mathematical calculations: + for
addition ( a + b ), - for subtraction ( a - b ), * for multiplication ( a * b ), / for
division ( a / b ), and % for modulus, which gives the remainder of a division ( a
%b )
Typescript Development 25
Unary Operators
Unary operators work on a single operand, while other operators need two or
more. For example, a++ and a-- are unary operators because they change only
one variable. There are two types: pre and post. In post increment ( a++ ), the
value increases after using the variable, while in pre increment ( ++a ), it
increases before using it. Similarly, in post decrement ( a-- ), the value
decreases after use, and in pre decrement ( --a ), it decreases before use.
When we say “use,” it simply means running that variable, like just writing a++
or ++a ; it doesn’t matter whether you print it or not, the change still happens.
For example, let a = 5; a++; ++a; a--; --a; — here, the value goes from 5 → 6 → 7 → 6
→ 5.
Assignment Operators
Assignment operators are used to assign values to a variable: = assigns a
value ( a = 10 ), += adds and assigns ( a += 5 is the same as a = a + 5 ), -=
subtracts and assigns ( a -= 5 is the same as a = a - 5 ), *= multiplies and assigns
( a *= 5 is the same as a = a * 5 ), and /= divides and assigns ( a /= 5 is the same
as a=a/5 )
Comparison Operators
Comparison operators are used to compare two values and return true or false :
== checks if values are equal, === checks if values and types are equal and
use it in maximum cases unless you does not care about the data type and you
just want to compare value, != checks if values are not equal, !== checks if
values or types are not equal, > means greater than, < means less than, >=
means greater than or equal to, and <= means less than or equal to
Logical Operators
Logical operators are used to combine conditions and return true or false : &&
(AND) returns true if both conditions are true, || (OR) returns true if at least
one condition is true, and ! (NOT) reverses the logical state of a condition
Typescript Development 26
??operator (Nullish Coalescing) gives a default value only if a variable is null
or undefined . For example, let name = null; let defaultName = name ?? "Guest"; gives "Guest"
because name is null, but let age = 0; let defaultAge = age ?? 18; keeps 0 because it’s not
null or undefined
same, but it’s stricter: it doesn’t convert types like == , and unlike === , it treats
-0 and +0 as different and considers NaN equal to NaN . For example, [Link]('1',
1) → false, [Link](NaN, NaN) → true, [Link](-0, 0) → false. In short, use == for
loose comparison with conversion, === for exact value and type, and [Link]()
String Operators
String Operators: + joins two strings together, and += adds one string to
another. Example: let str = "Hello, " + "World!"; str += " Bye!";
Optional operator
Optional operator ? in TypeScript is used to make a property or parameter
optional, which means it may or may not be provided. For example, interface User
{ name: string; age?: number } lets you create let user1: User = { name: "Ali" } without age, or let
Conditions in Typescript
Typescript Development 27
Conditional statements are used to take decisions in code, so that we can
perform different actions based on different conditions.
3. Based on that output, the program decides whether to run the code block.
If the condition is true, the block of code runs. If false, it does not. This
process helps the program decide which parts of the code to execute
depending on the condition’s outcome.
For simplicity, we usually just focus on the condition and don’t overthink the
internal steps. The else part is optional but recommended, as it handles the
false case.
Typescript Development 28
If you have a single statement after if or else , you can skip the curly braces
{} — but if there’s more than one statement, you must use curly braces. It is
generally recommended to always use curly braces for clarity and safety.
if (condition1) {
// code if condition1 is true
} else if (condition2) {
// code if condition1 is false and condition2 is true
} else {
// code if all conditions are false
}
Ternary Operator
Ternery Operator
let age = 20;
let canVote = (age >= 18) ? "You can vote" : "You cannot vote";
[Link](canVote);
// Output: "You can vote"
Typescript Development 29
Switch Statements
switch (day) {
case "Monday":
[Link]("Start of the week");
break;
case "Friday":
[Link]("Weekend is near");
break;
default:
[Link]("Regular day");
}
Conditional Chaining
Optional chaining ( ?. ) is an operator used to safely access properties or
methods of an object without causing an error if something is null or undefined .
Whatever we write before ?. is first checked — if it exists, then the value after
it will be accessed or executed. If it does not exist, it will safely return undefined
instead of giving an error.
Typescript Development 30
Template literal
Template literals are strings made with backticks (``) that we used to make
strings and easily embed variables, expressions, or even ternary operators
inside them using ${} This also lets you write on multiple lines; when you
press enter, it's treated as a new line in the string.
Loop
Loop is used to repeat a block of code, inside loops normally we use unary
operators ( ++ or -- ) on update place to increase or decrease a value by 1, but
if we want to change it by more than 1, we use assignment operators like i=i+
n instead of unary + +
Repetition: Executing the same instructions again and again without changes
Iteration: Executing the same instructions with changes each time is called
iteration
break is used to stop a loop completely, and continue is used to skip the current
loop iteration and move to the next one.
1. for loop is used when you know exactly how many times you want to
repeat a block of code, In [Link], or any code running Typescript, in for
loop first of all the starting value is checked. Then the condition is
evaluated. If it is true, the code block runs. After the first run, if there is an
update, it is applied on the starting value, Then updated value is get, the
Typescript Development 31
condition is checked again based on that value, and the block runs again.
This repeats until the condition becomes false.
for (starting value; condition(how long the loop runs and when it stops); up
date) {
// code
}
Example:
2. while loop is used when you don’t know exactly how many times you want
to repeat a block of code, it keeps running while the condition is true.
while (condition) {
// code
}
Example:
let i = 0;
while (i < 5) {
[Link](i);
i++;
}
3. do while loop is used when you want to execute a block of code at least
one time, regardless of whether the condition is true or false.
do {
// code to be executed
Typescript Development 32
} while (condition);
4. for of Loop: for...of loop is used to perform iteration over arrays and strings
and to get values in this loop we don’t define starting value, condition, or
update— for...of handles that automatically. If more control is needed, a
regular for loop can be used. It counts only actual values or characters, not
the null terminator like in C, When the for...of loop iterates over a string, it
first goes to the memory address stored in the variable (like name ). It gets
the value from that address, stores it in a character variable, and then uses
pointer arithmetic to access the next characters. This process continues
until the entire string or array is processed, we can’t use it with object
5. for in Loop: For in Loop: The for...in loop is used to perform iteration over an
object, array, or string to get their keys or indices. We don’t manually
define a starting value, condition, or update for...in automatically goes
through each key or index. For an array or string, it gives the index, which
we use to get the actual value. For an object, it gives the key, which we use
to access its corresponding value.
let student = {
name: "Abdullah",
age: 21,
univeristy: "VU",
isStudying: true,
};
Typescript Development 33
[Link](`${value} value is: ${student[value]}`);
}
Type Casting
Type Casting / Type Conversion means changing a value from one data type
to another. This can happen automatically (implicit / type coercion) when the
language converts it for you, like JavaScript turning "5" into 5 when needed,
or manually (explicit) when you tell it to convert using methods like parseInt() ,
parseFloat() , or toString()
Custom Types
To create your own custom type in TypeScript, use the type keyword, give it a
name, then write = and define the type. This is called a type alias. It helps you
give a simple name to any complex type so you can reuse it easily. For
example, type ID = number | string; means the type “ID” can be either a number or a
string. You can then use it like let userId: ID = 123; or let anotherId: ID = "abc"; . This makes
your code cleaner and easier to understand because you don’t have to repeat
long type definitions again and again — you just use the alias name instead.
Next, to allow a variable to store different kinds of values, use a Union Type
with the | symbol. For example, function combine(input1: string | number, input2: string | number) {
return input1 + input2; } means both values can be either a string or a number. But if
you want to merge two types into one single type that includes all their
properties, use an Intersection Type with the & symbol, like type AB = A & B; . This
makes a new type that has everything from both A and B.
Typescript Development 34
// Union Type
function combine(input1: string | number, input2: string | number) {
return [Link]() + [Link](); // converts both to string for sa
fe addition
}
// Intersection Type
type TypeA = { name: string };
type TypeB = { age: number };
type TypeAB = TypeA & TypeB; // new type has both name and age
let person: TypeAB = { name: "Ali", age: 25 }; // ✅ must have both properti
es
TypeScript Interfaces
Interfaces are simple rules that tell an object or class exactly which properties
and methods it must have, so your code stays clean and consistent; without
interfaces, objects can miss required fields and errors will appear later at
runtime. You use an interface by writing something like interface User { name: string;
age: number } and then creating an object that must follow this shape, Remember,
Admin extends User , it means Admin gets all the rules from User and also adds its
own rules. So Admin must have name , age , and its own role .
Typescript Development 35
Types vs Interfaces: both describe the shape of data, but type can create
unions and advanced combos, while interface is mainly for object/class shapes
and can be extended or merged.
Interface merging means TypeScript allows you to write the same interface
name again, and TypeScript will combine all the fields into one final interface.
This helps when you want to add more rules later or when libraries want to
extend existing interfaces. Hybrid types are special interfaces where one
value behaves like both a function and an object at the same time — that
means you can call it like a function, and also store properties on it like an
object. These features help you write code that is clean, organized, and easy
to understand, Here counter works like a function (you can call it), and also
like an object (it has a count property).
Interface Declaration + Merging Example
interface Box {
size: number;
}
interface Counter {
(): number; // function rule
count: number; // object property rule
}
Typescript Development 36
function createCounter(): Counter {
const fn = () => ++[Link];
[Link] = 0;
return fn;
}
Type Compatibility
Type Compatibility means whether both types have the same structure or not.
To check this, TypeScript focuses on the shape of the types, not their names.
If two objects have the same properties with the same data types, they’re
compatible and can be assigned, like interface Point { x: number; y: number } let p1: Point = { x:
, but if one has extra or missing
10, y: 20 }; let p2 = { x: 10, y: 20 }; p2 = p1; // same structure
properties like let p3 = { x: 10, y: 20, z: 30 }; p1 = p3; // different structure , TypeScript gives an
error. So use this to check if two types can safely share data by comparing
their structure, not their names.
Classes
What is Class & how to create it
A class is a template used to create objects with properties and methods.
Inside a class, we can directly define property values (like name = "Abdullah"; ), or
we can manually assign them later by writing [Link] = value most of
the time in class we don’t assign values because it is a template we create an
object from a class using the new keyword like let s1 = new Student(); . A class can
also have a special method called a constructor, which automatically runs
when the object is created. We can use it to assign property values or run
some code at the time of object creation.
If we want to use the properties defined inside the class — whether inside
methods, arrays, objects, or template literals — we always write [Link] .
The this keyword means the current object made from that class. We can also
Typescript Development 37
create a variable and instantly use it by writing [Link] while defining or
using it.
Constructor Overloading
Constructor is a function which runs automatically when new object is created
from the class, If both parent and child classes have a constructor, then inside
the child’s constructor we must first call the parent’s constructor using super() .
This ensures the parent’s part runs first, and also, Typescript requires that you
use super() before using the this keyword. You can also pass arguments inside
super() to send values to the parent constructor if you want it to perform some
operation, To use a parent class method inside the child class, write
[Link]() , and to use or access inherited properties, write
the child class itself, Constructor overloading means you can create the same
class using different inputs by making parameters optional.
Others
Access modifiers ( public , private , protected ) control who can read or change a
property, keeping your class safe. Polymorphism means one function or
method can do different things depending on the object that calls it; for
example, the same method sound() makes a dog say “Woof” and a cat say
“Meow”. Abstract classes are base classes you cannot create objects from;
they only guide child classes. Method overriding means if a child class has the
same method, it will replace the parent’s method.
Class + Constructor
class Person {
constructor(public name: string, public age: number) {}
}
Typescript Development 38
const p = new Person("Ali", 20);
class User {
constructor(public name: string, public age?: number) {}
}
Access Modifiers
class Bank {
public accName = "Ali"; // anyone can access
private balance = 5000; // only inside class
protected pin = 1234; // class + children
}
Inheritance
class Animal {
speak() { [Link]("Animal sound"); }
}
class Animal {
speak() { [Link]("Generic sound"); }
}
Typescript Development 39
class Cat extends Animal {
speak() { [Link]("Meow"); } // overriding
}
new Cat().speak();
Abstract Class
Type Guards
Type Guards mean telling TypeScript exactly what type a variable currently
has, especially when using custom types or variables that can have more than
one type. Without this, TypeScript can’t know the type, and with type guards
we can perform different actions based on the type. Tools for Type Guards
include: using typeof to check basic types like strings or numbers, instanceof to
see if an object is an instance of a specific class, Type Predicates to create
custom functions that return true/false for a type, and truthiness or equality
checks to narrow types using logical conditions.
Using typeof – for basic types like string or number:
Typescript Development 40
}
}
Typescript Development 41
[Link]("No value");
}
}
Function
Functions
Built in functions
Custom Functions
var , only the declaration goes up, not the value, so [Link](x); var x = 5; prints
undefined . However, hoisting does not work with let , const , arrow functions, or
Typescript Development 42
anonymous functions because they are stored in variables that are not hoisted.
For example, sayHi(); const sayHi = function() { [Link]("Hi"); }; or greet(); const greet = () =>
both cause errors because the functions are assigned to
[Link]("Good Morning");
Normal Function
function greet() {
[Link]("Hello!");
}
let sayHello = greet; // you can store a function inside a variable
Arrow Function
// Arrow functions are short and simple, best for small tasks or callbacks a
nd don’t have
// own `this`.
IIFE
An IIFE (Immediately Invoked Function Expression) is a function that runs as
soon as it is created. You wrap it in round brackets and also add round
brackets after it and it executes right away without needing a separate call like
this (function () { [Link]("This runs immediately!"); })(); , It’s mainly used to keep variables
private and prevent them from affecting the global scope.
Typescript Development 43
function inner() { [Link](name); } return inner; } let greetClosure = outer(); greetClosure(); yahan inner
function ne name ko yaad rakha. The arguments object lets you access all values
passed to a function without naming them, jaise function greet() { [Link]("You passed
. Built-in Functions are ready-made
" + [Link] + " arguments"); } greet("Ali", 20);
Typing Functions
Typing Functions mean giving types to function parameters and return
values so TypeScript knows what kind of data to expect and return. Function
Overloading means defining multiple ways to call the same function with
different parameters or types. Rest Parameters let you handle any number of
arguments as an array with a specific type.
Error Handling
Try, Catch Block
Error handling mean managing problems that can occur during code execution
so the program doesn’t crash. The most common way is using try and catch .
You put the code that might cause an error inside a try block, and if an error
occurs, it jumps to the catch block where you can handle it. The catch block
Typescript Development 44
receives an error object (often called err ) that contains information about the
error.
The err inside catch(err) is just a variable name you choose. Its value comes
from Typescript automatically whenever an error happens inside the try
block, the JS engine creates an error object and passes it into that variable.
You don’t assign it yourself; JS does it for you.
try {
let result = 10 / 0; // some code that may cause error
[Link](result);
} catch (err) {
[Link]("An error occurred:", [Link]);
}
try {
[Link](divide(10, 0));
} catch (err) {
[Link]("Error occurred:", (err as Error).message); // catch error
}
TypeScript has built-in error objects like Error , TypeError , and ReferenceError .
These objects give information about what went wrong so you can handle
different kinds of errors properly. For instance, you can check the type of error
and respond differently:
try {
let obj: any = undefined;
Typescript Development 45
[Link]([Link]); // ReferenceError
} catch (err) {
if (err instanceof TypeError) [Link]("Type Error!");
else if (err instanceof ReferenceError) [Link]("Reference Error!");
else [Link]("Some other error:", err);
}
Generics
Generics in TypeScript let you create reusable components or functions that
can work with any type instead of a single specific type. This makes your
code flexible and type-safe. For example:
Generic Constraints let you limit what types can be used with your generics
so that only certain types are allowed. For example:
Decorators
Decorators in TypeScript let you add extra behavior or information to classes,
methods, or properties without changing their original code. For example,
Typescript Development 46
using a decorator, you can automatically log when a method is called, like in
the code where @log prints the method name and arguments whenever add is
run.
Utility Types
Utility Types in TypeScript are built-in tools that help you manipulate types
easily. Object Utilities like Partial<T>make all properties optional, Pick<T, K>
selects certain properties, Omit<T, K> removes some properties, and Record<K, T>
creates an object with keys K and values T. Union Utilities like Exclude<T, U>
removes types from a union, Extract<T, U> keeps only types that exist in both,
and NonNullable<T> removes null and undefined . Function Utilities like Parameters<T>
gets the parameter types of a function, ReturnType<T> gets its return type, and
Awaited<T> unwraps a Promise. Readonly makes properties unchangeable.
TypeScript Modules
Typescript Development 47
TypeScript Modules help you organize and reuse code. Namespaces are used
to organize code internally within a file. External Modules let you import and
export code between different files, like export function greet() {} and import { greet }
from './file' . Ambient Modules are used to declare types for libraries that don’t
However, remember that the window object exists only inside the user’s
browser, not on your server. This means when you write Typescript to
manipulate user window, it runs inside the user’s browser window, You can’t
access or control someone else’s browser window from outside; you can only
control the window of the page or website that your code is running on.
When a web page opens, the browser first reads the HTML and converts it into
a tree-like structure. This structure is stored inside the document object. The
Typescript code runs inside the window object, and whenever we want to
change something on the page, Typescript updates the tree structure inside
the document.
Typescript Development 48
DOM stands for Document Object Model. Here, “Document” means the object
that holds your entire HTML page, and “Model” means the way that HTML is
represented in a tree-like structure inside the object.
The CSS is not stored inside the window object the browser keeps it separately
and applies its styles to the elements inside the document object.
In the DOM, there are three main types of nodes: element nodes, text nodes,
and comment nodes. Most of the time, we work with element nodes because
they represent actual HTML tags like <div> or <p> . When we deal with child
elements, we use properties like firstChild, lastChild to access them. While
looping through child elements, it’s common to use a loop to perform actions
on each child. Also, remember that inline styling (like style="color:red" ) has the
highest priority, so it’s better to avoid using it often, When writing HTML or
Typescript, if you’re already using double quotes outside, then you must use
single quotes inside to avoid errors
[Link]("idName") , [Link]("className") ,
[Link]("div") , or the modern one —
[Link](".className") and [Link](".className") . To update an
element, we can change its content using innerText , innerHTML , or textContent , and
even change its attributes with setAttribute("attrName", "value") . To delete an element,
just call [Link]() and it will disappear from the page. We can also place
elements in the DOM using methods like [Link](el) to add at the end,
[Link](el) to add at the start, [Link](el) to add before, and [Link](el)
to add after.
To see a value as normal text with tags, use [Link]() . To see a value as an
object with all its properties and methods, use [Link]()
Typescript Development 49
or getComputedStyle(element).propertyName . To update, just
[Link]
change the value again, like [Link] = "green" . And to delete or reset
a style, set it to an empty string like [Link] = "" . You can also
add or remove CSS classes using [Link]("className") or
[Link]("className") , which is an easy and clean way to control styles
from CSS instead of inline.
Events
An event is a change in the state of an object, and we use an event listener to
listen it, Inside the event listener, we have an event type and an event handler
function, which will be executed when the event occurs.
Types of Events
An event trigger is same as event happening. Every node (or element) in the
DOM can produce or respond to an event, There are many types of events like
mouse events (click, hover), keyboard events (key press, key up), form
events (submit, change), and print or window events. These events can
happen because of user actions (like clicking or typing) or sometimes due to
the environment, such as a low battery warning or internet disconnection.
Ways to handle event
Event handling in Typescript means running some code when something
happens on a webpage, like when we click a button or press a key. There are
three simple ways to do it. The old way is to write the event directly in HTML
like <button Me</button> , but it mixes HTML and JS. The
second way is by using a property like [Link] = () => { [Link]("Clicked"); } , which
is cleaner but only one event can work at a time. The best and modern way is
by using addEventListener() , for example [Link]("click", myFunc) , which allows
many events and can be removed later with removeEventListener() . Event handling
helps make webpages interactive and smart.
If we want to remove an event listener, we must pass the same function
reference to removeEventListener() that we used with addEventListener() . That’s why we
store the function inside a variable, because when a function is stored in a
variable, the variable keeps the reference (or address) of the function in
memory. This means both addEventListener() and removeEventListener() point to the
Typescript Development 50
same exact function. If we don’t use a variable and instead write a new
anonymous function, Typescript treats it as a completely different one, so it
won’t get removed.
If you write event code both inside HTML and in Typescript, the Typescript one
will win and run instead of the HTML one. If you use .onclick many times on the
same element, only the last one will work because it replaces the old ones. But
if you use addEventListener() , you can add many event functions for the same
event, and all of them will run.
When an event happens, Typescript gives you an event object with useful info
about what just happened. You can use [Link] to know which event occurred
(like "click" or "keydown"), [Link] to know which element got clicked,
[Link] to know which element the listener is attached to, [Link]
and [Link] to get mouse position, [Link] to check which key was
pressed, [Link]() to stop default behavior (like stopping a form from
submitting), and [Link]() to stop the event from bubbling up.
Remember In Typescript, every HTML element is an object, so you can use
.name (or .id , .class ) to get its attribute, for example <select name="from"></select> and
then in JS [Link]([Link]); // prints "from"
Assertions
In TypeScript, the as syntax lets you manually tell TypeScript the type of a
value, like let x = value as string . as const locks a value so it becomes a literal,
unchangeable type, for example let nums = [1, 2] as const . as any forces a value to be
any type, bypassing type checking, but should be used carefully. Non-null
Assertion ( ! ) tells TypeScript a value is definitely not null or undefined, like
element!.value . The satisfies keyword allows you to check that a value meets a
type requirement without changing its inferred type, for example: let person = {
Typescript Development 51
object, in a standalone function it may be undefined (in strict mode), in event
handlers it refers to the element, and in arrow functions it keeps the this of its
surrounding scope. Explicit Binding uses call , apply , or bind to manually set
what this refers to, and Function Borrowing lets you reuse methods from one
object in another, like using [Link] on an array-like object.
function greet() {
[Link]("Hello!");
}
function execute(callback) {
callback();
}
execute(greet); // Output: Hello!
Typescript Development 52
execute(function() {
[Link]("Hi!");
}); // Output: Hi!
execute(() => {
[Link]("Hey!");
}); // Output: Hey!
const obj = {
sayHello: function() {
[Link]("Hello from object!");
}
};
execute([Link]); // Output: Hello from object!
Callback Hell
Typescript Development 53
}, 1000);
}
fetchUser(1, () => {
fetchUser(2, () => {
fetchUser(3);
});
});
Promises
A Promise is a special Typescript object that is return as a value by function,
by default its state is pending mean it does not send the actual data
immediately. The real data becomes available only when the promise is
fulfilled or rejected. It’s like saying, “If the code runs successfully, I’ll give you
the result. If there’s a problem, I’ll give you an error.” This helps us plan what to
do next. Promises make code cleaner and help us avoid callback hell when
dealing with dependent tasks.
resolve(value) means the task succeeded, and reject(error) means the task failed.
and reject are built-in Typescript functions, so you don’t need to define
resolve
them. You simply use resolve for success and reject for errors, passing a value
or error message inside. In most cases, we consume promises rather than
create them ourselves.
Promise States
A promise can be in three states. When it’s pending, the task is still running
and not finished yet. When it’s fulfilled (resolved), the task finished
successfully and returned a value. When it’s rejected, the task failed and
returned an error. When a system or API returns a promise, it gives a pending
promise object, not the final data. The real data comes only after the promise
is fulfilled or rejected.
Typescript Development 54
Ways to Handle Promise
Handling Promises (.then, .catch, .finally)
When a promise is resolved, it connects to the first .then() in the chain and
passes the resolved value to it. From there, we can chain more .then() calls to
handle results step by step. If any step fails, .catch() handles the error, and
.finally() always runs no matter if the promise succeeds or fails.
Remember Each .then() returns a new promise. Use return inside .then() to pass
the resolved value to the next .then() in the chain.
Example:
When tasks depend on each other, we use await sequentially — one after
another — to make sure each step finishes before the next starts. But when
Typescript Development 55
tasks are independent and do not rely on each other’s result, they can run in
parallel using separate promises or by using [Link](), which runs all tasks
together without blocking the code.
What Is the Difference Between the these Three Ways to Handle Time-
Consuming Tasks?
When we want to run some code after calling a function that takes time, there
are three main ways. The first is the callback method, where we call a function
and pass another function inside it; this inner function contains the code we
want to run after the main work finishes. The second is using a Promise with
.then()and .catch() methods, where we call a function that returns a Promise,
write the code we want to run later inside .then() , and handle errors inside
.catch() . The third is the async/await method, which is also based on Promises;
we call the function inside an async function, use await before it, and the code
written after await runs only after the Promise finishes. In all three methods, we
first run a function and then attach the code we want to run later, but the
difference is where we place that code: inside the callback, inside
.then() / .catch() , or after await .
In all three cases, the time-taking part runs asynchronously, which means it
runs separately while the rest of the code continues. JavaScript does not stop
or wait for it; the main program moves forward. When the asynchronous task
finishes, JavaScript runs the code we attached — either the callback, the .then()
block, the .catch() block, or the code after await . For example, in all three
methods, if we print "Start" before calling the function, "End" after calling it, and
print the result inside the callback, .then() , or after await , the output will always
be:
Start
End
Data received
This clearly shows that the long task works in the background while the rest of
the code keeps running.
Typescript Development 56
Fire-and-Forget Case (Next instruction does NOT depend on previous time-
taking task)
When the next instruction (whether time-taking or not) is not dependent on a
previous time-consuming task, and we don’t need the result of that task, it’s a
fire-and-forget case, We just start the task and move on it runs in the
background without blocking code, If time-consuming task is non promise like
setTimeout or any async operation we simply call it and move to the next
instruction. If it’s a Promise, we can call it directly and optionally use .catch() to
handle errors. If the Promise is called inside an async function, we use await to
wait for it inside that function, while any code outside the async function runs
normally as the async task continues in the background.
Callback
[Link]("Task 1 started");
setTimeout(() => {
[Link]("Task 1 finished after 2s");
}, 2000); // runs in background
function downloadFile() {
return new Promise((resolve) => {
setTimeout(() => {
[Link]("File downloaded");
resolve();
}, 2000);
});
}
// Fire-and-forget
Typescript Development 57
downloadFile(); // we don't wait
[Link]("Moving to next step");
Typescript Development 58
function getData(callback) {
setTimeout(() => {
let data = "User Data";
callback(data); // pass result to next step
}, 2000);
}
getData((result) => {
[Link]("Received:", result);
[Link]("Now showing user profile"); // dependent
});
function getData() {
return new Promise((resolve) => {
setTimeout(() => resolve("User Data"), 2000);
});
}
getData().then((result) => {
[Link]("Received:", result);
[Link]("Now showing user profile");
});
function getData() {
return new Promise((resolve) => {
setTimeout(() => resolve("User Data"), 2000);
});
}
Typescript Development 59
[Link]("Received:", data);
[Link]("Now showing user profile");
}
showProfile();
fetchUser(1, () => {
fetchUser(2, () => {
fetchUser(3);
});
});
function fetchUser(id) {
return new Promise((resolve) => {
setTimeout(() => {
[Link](`Fetched user ${id}`);
resolve(`User ${id} data`);
}, 1000);
Typescript Development 60
});
}
Fetched user 1
Returned from 1: User 1 data
Fetched user 2
Returned from 2: User 2 data
Fetched user 3
Returned from 3: User 3 data
All users fetched successfully
function fetchUser(id) {
return new Promise((resolve) => {
setTimeout(() => {
Typescript Development 61
[Link]("Fetched user", id);
resolve();
}, 1000);
});
}
getAllUsers();
Typescript Development 62
Fetch API
fetch is a Typescript function, not a method, to which you give a URL and
parameters, and it calls the API for you. It doesn’t have data itself; the API
responds with promise, and fetch returns that Promise to you. Both fetch and
axios act as middlemen between your code and the API, handling repquests
and delivering responses.
To read the data from the response, we use [Link]() . This function
converts the raw response into a JavaScript object or array. We usually use
with [Link]() because it takes time to convert the raw data into JSON.
await
Once converted, the data can be an array or an object depending on what the
server sends. If the server sends data in square brackets [...] , you get an array
and access items using [0] , [1] , etc. If it sends data in curly braces {...} , you
get an object and access items using keys like [Link] .
Always check if the data is a list (array) using [Link](data) . After that, write
your code to handle both situations: if it is a list, do actions for each item; if it is
an object, do actions directly on its keys. If the data is more complicated,
check if certain keys exist before using them, or make a simple plan (schema)
of what data should look like to avoid errors when the program runs.
There are different formats to work with data when talking to a server. AJAX
stands for Asynchronous JavaScript and XML, but now we usually use JSON
instead of XML. Some people call it AJAJ (Asynchronous JavaScript and
JSON) or just JSON requests. The idea is the same: call the server
asynchronously and get data back. When calling APIs, we also use HTTP
verbs like GET, POST, PUT, DELETE to tell the server what action we want.
Status codes show the result of the request, and headers carry extra
information like content type, authorization, and other metadata for both the
request and the response.
JavaScript Modules
JavaScript Modules let you organize and share code between files. ESM
(ECMAScript Modules) is the modern standard using import and export , like
export function greet() {} and import { greet } from './file' . Common JS is the older [Link]
style, using [Link] and require() , like [Link] = greet; const greet =
require('./file'); .
Typescript Development 63
Iterators & Generators
Iterators let you customize how objects are looped over, so you can control
the sequence of values. Generators are special functions that can pause and
resume execution, using function* and yield , which is useful when you want to
produce values one by one instead of all at once.
Memory Management
This is about how JavaScript handles memory—allocating it for variables and
objects, using it while needed, and releasing it when done. Garbage
Collection automatically cleans up memory that is no longer referenced, so
developers don’t have to manually free memory.
Equality Algorithms
JavaScript has different ways to compare values. Loose equality ( == )
converts types before comparing, strict equality ( === ) compares without
conversion, and [Link] checks if two values are exactly the same using the
SameValue or SameValueZero algorithm, which can handle edge cases like NaN .
Advanced Types
TypeScript provides tools to create flexible and powerful types. Mapped Types
create new types from old ones, Conditional Types change types based on
logic, Template Literal Types combine string patterns, and Recursive Types
allow types to refer to themselves, which is useful for nested structures.
JSON
JSON is a way to store and share data in a structured format that looks like a
Typescript object, but its data type is string, so we can use string methods on
Typescript Development 64
it. Because it has keys and values like an object, we convert it into a
Typescript object using [Link]() to access values, add, update, delete, loop,
or use object methods. To send data back, we convert it to JSON text using
[Link]() . JSON can store six types of values: strings, numbers, boolean,
arrays, objects, and null, always write keys in strings.
{
"name": "Abdullah",
"age": 20,
"hobbies": ["coding", "reading"],
"isStudent": true
}
Aliases
In [Link], aliases are shortcuts for folder paths to make imports short and
clean. "@/*": ["./*"] means @ points to the root folder of your project—the main
folder you open in VS Code containing [Link] . The * is a wildcard for any
file or folder inside the root. To create your own shortcuts, open [Link] or
[Link] and add paths under [Link] like @components/* , @pages/* ,
@utils/* , and @styles/* . Then when you write import ButtonDeletePost from
Local Storage
Local storage is a small storage space in the browser where Typescript can
save data like names, settings, or scores as key-value pairs. For example, you
can save something using [Link]("name", "Abdullah") , get it back anytime
using [Link]("name") , remove one item with [Link]("name") , or
clear everything using [Link]() . The saved data stays even if the user
closes the browser and will remain there unless the developer or user deletes
it, or a very long period passes, and it is used to remember information in the
browser so the user doesn’t have to enter it again.
Typescript Development 65
First install the library using npm. Then import it inside your TypeScript file and
try to use it. If TypeScript shows no error, it means the library already has
TypeScript support, and nothing else is needed. If TypeScript shows errors like
“Cannot find module” or “has any type,” it means the library does not provide
TypeScript information. In this case, create a folder named types, then create a
file like [Link] inside it. This file will explain the functions that the library
gives you, so TypeScript understands them.
Inside the .[Link] file, write a declare module block. Inside it, list every function you
want to use from that library. For each function, write what input it needs and
what output it gives. Then add the types folder inside your [Link] so
TypeScript can read it. After saving, restart your dev server so TypeScript
starts using this new information.
Typescript Development 66