Typescript Slides
Typescript Slides
1
Introduction
TypeScript is a superset of JavaScript that adds optional type annotations and other features such as interfaces, classes, and
namespaces. JavaScript is a dynamically-typed language that is primarily used for client-side web development and can also be
used for server-side development.
Types: TypeScript has optional type annotations while JavaScript is dynamically-typed. This means that in TypeScript, you
can specify the data type of variables, parameters, and return values, which can help catch type-related errors at compile-
time.
Syntax: TypeScript extends JavaScript syntax with features like interfaces, classes, and namespaces. This provides a more
robust and organized structure for large-scale projects.
Tooling: TypeScript has better tooling support, such as better editor integration, type checking, and code refactoring.
Backwards Compatibility: TypeScript is fully compatible with existing JavaScript code, which means you can use TypeScript
in any JavaScript environment.
2
Introduction
Typescript was created by microsoft addressing the shortcomings of JavaScript
Typescript is build on top of javascript so every javascript file is a valid typescript file
Typescript is an extended version of javascript: it needs a TS compiler for the browser to execute the code.
3
Pros & Cons
Pros
More robust
Easily Spot Bugs
Readability
Popular
Cons
There is always a compilation step (browsers can not execute typescript code so it needs to be translated into javascript by
a typescipt compiler => Transpilation)
Discipline in code
More to learn
Not true Static Typing
4
Setup
To use the typescript compiler we need to install the package: npm i -g typescript
Create a typescript file with ts as extention. Any javascript code is a valid typescript code.
Then compile your code using tsc index.ts in your cmd => a compiled javascript version of the typescript file will be created
5
Syntaxe
let age: number = 20;
// age = "a"; // we can not do this!
Notice the var keyword. By default the typescript compiler uses an older version of javascript.
6
Configuration
We create the configuration file by executing the command: tsc --init .
In tsconfig.json we have a number of setting that most of them are commented off
"target": "es2016",
Here we specify the version of javascript that we want. ES2016 is the safest option since it is compatible with all browsers
/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
"rootDir": "./src" /* Specify the root folder within your source files. */,
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
"removeComments": true, /* Disable emitting comments. */
"noEmitOnError": true /* Disable emitting files if any type checking errors are reported. */,
With this configuration file, to compile the file we can just write tsc in the cmd
7
Basic TS Types
TS is a statically typed language. The type cannot be changed during program execution. This allows you to reduce a large
number of errors and identify many of them even at the compilation stage. TS has several simple data types: numbers, strings,
structures, Boolean. It supports all types that are available in JS, complementing the convenient enum type
8
Built-in Types
let age = 20;
let decimal: number = 6;
let text = 'Typescript';
let name: string = "bob";
let is_published = true;
let level;
Typescript can annotate the variable to their specific type without the need to specify it. If we declare a variable with no value,
its type will be set to any.
9
"Any" type
let level;
level = 1;
level = "a";
Because the variable level is of type any we will not have any errors. But this defies wht typescript was created which is type
safety!
10
"Any" type
One way of solving this problem is to annotate the variable with the type any
But we can use the tsconfig file to avoid the error when you implicitly use a variable with type any
"noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
11
Arrays
In javaScript we could write
However if we want to specify that our array should contain only numbers, we can use typescript and write
If we declare an empty array, its elements will be of type any, hence we will have the possibility to have an array with elements
of different types.
Tuples are useful only if we have two elements. Any more then that and the code will be messy and unreadable.
console.log(x[0].substring(1)); // OK
console.log(x[1].substring(1)); // Error, 'number' does not have 'substring'
13
Tuples
Optional Tuple Elements:
Like function signatures, we can also have optional tuple elements. This is achieved with the help of the symbol? in the tuple
definition:
14
Enum
Enum is a special type borrowed from other languages like C#, C ++, and Java that provides a solution to the special numbers
problem. Enum binds a human-readable name for a specific number. As in languages like C#, the enum type is a more
convenient way to give clear names to a set of numeric values Instead of:
const small = 1;
const medium = 2;
const large = 3;
We define an enum as
By default Small will have the value 0, Medium 1 and Large 2 but we can change it as follows
15
Enums
In the js file created we have:
"use strict";
var Size;
(function (Size) {
Size[Size["Small"] = 1] = "Small";
Size[Size["Medium"] = 2] = "Medium";
Size[Size["Large"] = 3] = "Large";
})(Size || (Size = {}));
let mySize = Size.Medium;
console.log(mySize);
But if we use:
"use strict";
let mySize = 2;
console.log(mySize);
16
String Enums
Another variant of the enum type is a string enumeration, in which numeric values are replaced with strings:
enum DoorStateString {
Open = "open",
Closed = "closed",
Ajar = "ajar"
}
var openDoorString = DoorStateString.Open;
console.log('openDoorString = ${openDoorString}');
17
Void
Void is the opposite of Any: the absence of any types. It is most often used as the return type of functions that do not return
any value.
Declaring variables with the void type is useless, because you can only assign them undefined or null values.
18
NULL & Undefined
The Null and Undefined types correspond to the same types in JS. These types are subtypes for all other types by default.
If you declare a variable of type null or undefined, then such a variable can only be assigned the value null or undefined,
respectively, which has no practical application.
19
Non-Null assertion
The non-null assertion operator (!) is a type assertion in TypeScript that allows you to tell the compiler that a value will never be
null or undefined.
// we use the non-null assertion operator to tell the compiler that name will never be null
let nameLength = name!.length;
The non-null assertion operator is used to assert that a value is not null or undefined, and to tell the compiler to treat the value
as non-nullable. However, it’s important to be careful when using the non-null assertion operator, as it can lead to runtime
errors if the value is actually null or undefined .
20
Type assertions
Sometimes you find yourself in a situation where you know more about the value of a variable than TS does. This usually
happens when you know that the type of an entity may be more specific than its current type. Type assertion is like typecasting
in other languages, but it doesn’t do any special checks or data restructurings. The type conversion has no effect at the
execution stage of the program and is used only by the compiler. TS assumes that the programmer will do all the necessary
checks that are required.
The type conversion can be done in two ways. The first is the use of angle brackets syntax
21
Functions
The TS language slightly expands the capabilities of functions compared to JavaScript, making working with them even more
convenient.
in tsconfig.json
"noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
"noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
"noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */,
22
Functions
In TypeScript, functions can be typed in a few different ways to indicate the input parameters and return type of the function.
Function type:
console.log(add(1, 2)); // 3
console.log(add('Hello', ' World')); // "Hello World"
24
Objects
let employee = { id: 1 };
employee.name = "Amal";
let employee: {
id: number;
name: string;
} = { id: 1 };
employee.name = "Amal";
25
Objects
We can make the name property optional
let employee: {
id: number;
name?: string;
} = { id: 1 };
employee.name = "Amal";
let employee: {
readonly id: number;
name: string;
} = { id: 1, name: "Amal" };
26
Objects
let employee: {
readonly id: number;
name: string;
retire: (date: Date) => void;
} = {
id: 1,
name: "Amal",
retire: (date: Date) => {
console.log(date);
},
};
27
Advanced types
Type aliases
Unions and intersections
Type narrowing
Nullable types
The unknown type
28
Type aliases
Using type aliase we can create a custom type.
type Employee = {
readonly id: number;
name: string;
retire: (date: Date) => void;
};
29
Union Types
function kgToLbs(weight: number | string): number {
// Narrowing
if (typeof weight === "number") {
return weight * 2.2;
} else {
return parseInt(weight) * 2.2;
}
}
30
Intersection
type Draggable = {
drag: () => void;
};
type Resizable = {
resize: () => void;
};
Now the textBox variable is both of Draggable type AND Resizeble type
31
Literal types
// Literal (exact, specific)
let quantity: 50 | 100 = 50;
32
Nullable / undefined Types
By default typescript is very strict when working with null and undefined values, because it is the source of bugs in vanilla
javascript code.
greet(null);
greet(undefined);
33
Nullable / undefined Types
type Customer = {
birthday: Date;
};
34
Unknown
unknown is the type-safe counterpart of any. Anything is assignable to unknown, but unknown isn’t assignable to anything but
itself and any without a type assertion or a control flow based narrowing. Likewise, no operations are permitted on an unknown
without first asserting or narrowing to a more specific type.
35
Interfaces
Interfaces in TypeScript provide a way to define a contract for a type, which includes a set of properties, methods, and events.
It’s used to enforce a structure for an object, class, or function argument. Interfaces are not transpiled to JavaScript and are only
used by TypeScript at compile-time for type-checking purposes.
interface User {
name: string;
age: number;
}
In this example, the User interface defines the structure of the user object with two properties, name and age. The object is
then typed as User using a type-assertion: User.
36
Interface VS Types alias
Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an
interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface
which is always extendable.
Extending an interface
interface User {
id: string;
email: string;
}
interface User { name: string; }
// Now you can add all the three values to the User interface
const user: User = {
id: "2323232", email: "[email protected]", name: "Foo",
};
A class in TypeScript is defined using the class keyword, followed by the name of the class. The class definition can include
fields (also known as properties or attributes), methods (functions), and a constructor.
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log(`${this.name} is making a sound`);
}
}
class Base {
k = 4;
}
40
Classes (Constructor Overloading)
In TypeScript, you can achieve constructor overloading by using multiple constructor definitions with different parameter lists in
a single class. Given below is the example where we have multiple definitions for the constructor:
class Point {
// Overloads
constructor(x: number, y: string);
constructor(s: string);
constructor(xs: any, y?: any) {
// Only One definition of the Constructor
}
}
Note that, similar to function overloading, we only have one implementation of the consructor and it’s the only the signature
that is overloaded.
41
Classes (access modifiers)
In TypeScript, access modifiers are keywords used to control the visibility and accessibility of class properties and methods.
There are three access modifiers in TypeScript:
public : This is the default access modifier. Properties and methods declared as public can be accessed from anywhere,
both inside and outside the class.
private : Properties and methods declared as private can only be accessed within the same class. They are not accessible
from outside the class.
protected : Properties and methods declared as protected can be accessed within the class and its subclasses. They are
not accessible from outside the class and its subclasses.
Access modifiers in TypeScript allow you to define the level of visibility and accessibility of properties and methods in your
class, making your code more maintainable and secure.
42
Classes (access modifiers)
class Person {
private ssn: string;
private firstName: string;
private lastName: string;
getFullName(): string {
return `${this.firstName} ${this.lastName}`;
}
}
43
Abstract Classes
Abstract classes in TypeScript are classes that cannot be instantiated on their own and must be subclassed by other classes.
Abstract classes provide a blueprint for other classes and can have abstract methods, which are methods without a body and
must be overridden by the subclass. These classes are useful for defining a common interface or basic functionality that other
classes can inherit and build upon.
move(): void {
console.log('moving...');
}
}
44
Inheritance vs Polymorphism
Inheritance refers to a mechanism where a subclass inherits properties and methods from its parent class. This allows a subclass
to reuse the code and behavior of its parent class while also adding or modifying its own behavior. In TypeScript, inheritance is
achieved using the extends keyword.
Polymorphism refers to the ability of an object to take on many forms. This allows objects of different classes to be treated as
objects of a common class, as long as they share a common interface or inheritance hierarchy. In TypeScript, polymorphism is
achieved through method overriding and method overloading.
class Animal {
makeSound(): void { console.log('Making animal sound'); }
}
class Dog extends Animal {
makeSound(): void { console.log('Bark'); }
}
class Cat extends Animal {
makeSound(): void { console.log('Meow'); }
}
let animal: Animal;
For example, the following is a generic function that takes a single argument of any data type and returns the same data type:
In this example, the identity function takes a single argument of any data type and returns the same data type. The actual data
type is specified when the function is called by using <string> before the argument "Hello" .
46
TP: Book Reading tracker
Create an HTML file where we have a form that register new books (use tailwindCSS to style it)
Each book have a title(string), author(string), number of pages(number), status(String Enum), price (number), number of
pages read (number < number of pages), format(String Enum), suggested by(string), finished(boolean).
Status can have one of the following values: Read, Re-read, DNF, Currently reading, Returned Unread, Want to read
Format can have one of the following values: Print, PDF, Ebook, AudioBook
Be default finished is equal to 0, the finished value will change to 1 automatically when number of pages read is euqal to
number of pages
Create a class book have the following methods: a constructor, currentlyAt, deleteBook
Create a web page where we can track our reading by listing books and showing the percentage of reading for each book,
and a global section where you can see the total amount of book read and the amount of pages
47