

TypeScript
TypeScript
introductie


TypeScript?
TypeScript is JavaScript with syntax for types.
It is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.

TypeScript?
TypeScript is JavaScript with syntax for types.
It is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.
-
Superset (~ uitbreiding) van JavaScript
- Geldige JavaScript-code → Geldige TypeScript-code (syntactisch)
- Opgepast: niet in omgekeerde richting toepasbaar
- TypeScript compileert naar JavaScript

TypeScript
-
Strongly/statically typed languages
- data types are defined at compile-time and
can not change - e.g. TypeScript, Java, C#, Rust ...
- data types are defined at compile-time and
-
Loosely/dynamically typed languages
- data types are evaluated at run-time and
can change - e.g. JavaScript, Python, Ruby, PHP ...
- data types are evaluated at run-time and

TypeScript
let temperature = 20;
// wat is het type van deze variabele 'temperature' op lijn 1?
temperature = "warm";
// wat is nu het type van deze variabele?let temperature: number = 20;
// wat is het type van deze variabele 'temperature' op lijn 1?
temperature = "warm";
// TypeErrorJavaScript
TypeScript

Waarom TypeScript?
-
Voordelen
- Bugs ontdekken vóór code wordt uitgevoerd
- Expliciete code is vaak makkelijker leesbaar
- Betere code completion in IDE
- Bijkomende features t.o.v. JavaScript

Waarom TypeScript?
-
Nadelen
- Compilatie-stap: vergt tijd en resources
- Meer code nodig voor dezelfde uitkomst
- Minder flexibiliteit dan JavaScript
- Discipline nodig, anders wordt het een boeltje !

Waarom TypeScript?
let temperature = 20;
// Developer #10 schrijft de lijn hieronder
temperature = "warm";
// Maar heeft deze conversie over het hoofd gezien ...
const temperatureInFahrenheit = (temperature * 1.8) + 32;
// Bonus: wat is de waarde van temperatureInFahrenheit nu?
Type(s in Java)Script
-
Welke 8 types zijn er in JavaScript?
- Niet spieken!
We doen een rondje, elk om beurt.
- Niet spieken!

Type(s in Java)Script
-
Welke 8 types zijn er in JavaScript?
- null
- undefined
- number
- boolean
- string
- object
- BigInt
- Symbol
TypeScript
Werken met TypeScript


Werken met TypeScript
- Officiële documentatie:
Typescript Handbook - Geen zin om een nieuw project te initialiseren,
maar wil je toch wat Typescript oefenen?
Gebruik dan de officiële Typescript playground.

Werken met TypeScript
- Nieuw project?
Installeer, initialiseer & compileer
cd my-empty-folder
npm init -y
npm install typescript --save-dev
npx tsc --init
npx tsc
Werken met TypeScript
- Extensie:
.js→ .ts - Variabele declareren/initialiseren?
Definieer het type!
let temperature: number = 20;
let greeting: string = "Hello, students!";
let isThisCourseAwesome: boolean;
Werken met TypeScript
-
Functies
- Parameter type annotations
- Return type annotations
function sum(a: number, b: number): number {
return a + b;
}
Werken met TypeScript
-
Functies: parameter type + return type
- Als de return value van een functie niet gebruikt wordt, dan noemen we de return type void
function someFunc(): void {
console.log("Hi there!");
}- Onthou wel: elke functie in Javascript heeft een impliciete return value. Welke waarde is dat?

Werken met TypeScript
type Address = {
name: string;
postalCode: string;
city: string;
street: string;
houseNumber: number;
};
async function sendMail(address: Address): void {
// some logic to send physical mail goes here ...
}
// What errors will the compiler throw here?
sendMail({
postalCode: "9000",
city: "Ghent",
street: "Leeuwstraat",
houseNumber: "1",
});
Werken met TypeScript
// Who needs postal codes, right?
type Address = {
name: string;
postalCode?: string;
city: string;
street: string;
houseNumber: number;
};
async function sendMail(address: Address): void {
// some logic to send physical mail goes here ...
}
sendMail({
name: "Karel De Smet",
city: "Ghent",
street: "Leeuwstraat",
houseNumber: 1,
});
Werken met TypeScript
function greeting(firstName: string, lastName?: string): void {
const nameToPrint = lastName ? `${firstName} ${lastName}` : firstName;
console.log(`Hello ${nameToPrint}!`);
}
// We can just greet people by their first name, the last name is optional
greeting("Karel");
greeting("Karel", "De Smet");
Werken met TypeScript
-
Optional parameters (?)
- Side note:
je kan ook default parameters specifiëren in JS/TS
- Side note:
function greet(name, greeting = 'Hello') {
console.log(greeting + ', ' + name);
}
greet("Karel");
// "Hello, Karel"
greet("John", "Hi");
// "Hi, John"
Werken met TypeScript
-
Interfaces
- Zowel types als interfaces beschrijven de vorm van een object. In de meeste gevallen kan je ze 1 op 1 vervangen.
Meer weten? Lees zelf over de verschillen.
- Zowel types als interfaces beschrijven de vorm van een object. In de meeste gevallen kan je ze 1 op 1 vervangen.
// Basically the same as type Address from the previous slides
interface Address {
name: string;
postalCode?: string;
city: string;
street: string;
houseNumber: number;
};
Werken met TypeScript
function sum(arr: Array<number>): number {
return arr.reduce((a: number, b: number) => {
return a + b;
}, 0);
}
// Array<number> en number[] betekenen exact hetzelfde,
// je kiest zelf welke syntax je verkiest
Werken met TypeScript
-
Union type
- Hebben de array values mogelijk een verschillend type?
Dat lossen we op met een union type (|)
- Hebben de array values mogelijk een verschillend type?
const arrayOfNumberOrString: Array<number | string> = [];
arrayOfNumberOrString.push(1);
arrayOfNumberOrString.push("Hello world");
// Error: Argument of type 'boolean' is not assignable to parameter of type 'string | number'.
arrayOfNumberOrString.push(false);
Werken met TypeScript
-
Tuples
- Ken je de lengte van de array en weet je ook welk type van toepassing is op elke index? Dan spreken we van een tuple.
const stringNumberTuple: [string, number] = ["Weeks from shore", 2];
Werken met TypeScript
-
Literal type
- Wat als je het type van een variabele wil beperken tot
bv. een aantal specifieke strings?
- Wat als je het type van een variabele wil beperken tot
type Theme = "dark" | "light";
// Error: Type '"violet"' is not assignable to type 'Theme'.
const theme: Theme = "violet";
Oefeningen
- Werk voor deze oefeningen in de Typescript Playground
of maak lokaal een Typescript-project aan

Oefeningen
Oefening 1:
-
Declare and initialize the following variables with explicit types:
- username (string)
- age (number)
- isStudent (boolean)
- courses (array of strings)
- Log all of them to the console

Oefeningen
Oefening 2:
- Write a function multiply that takes two arguments of type number
and returns their product.

Oefeningen
Oefening 3:
-
Create an interface or type
Userwith the following properties:username(string)email(string)age(number, optional)isActive(boolean)
-
Then create a function
printUserInfothat takes a User object
and logs the user’s information to the console.

Oefeningen
Oefening 4:
- Create an interface or type
Productwith propertiesname,price, andcategory. Define logical types for each property. - Next, create an array of
Productobjects and write a functiongetTotalPricethat calculates the total price of all products in the array.

Oefeningen
Oefening 5:
- Write a function
formatInputthat takes a string or number as an argument.- If the argument is a number, return it as a string with a $ symbol in front (e.g., 100 -> "$100").
- If the argument is a string, just return it in uppercase.

Oefeningen
- Extra oefeningen
-
Total TypeScript: solving TS errors
- Kloon eerst Github repository
- Oefening 1 & 2
-
TypeScript exercises
- Oefening 1 & 2
-
Total TypeScript: solving TS errors
TypeScript
More TypeScript!


Type inference
- If you don't annotate the type,
TypeScript will infer it, hence type inference - Preferred for primitives
- Usually not advisable for object types, arrays ...
let greeting = "Hello world";
// The TypeScript compiler infers that greeting is of type string.
// There's no need to make it explicit.
const arrayOfStudents = [];
// TypeScript can not know what type of values we will store in this array.
// So it infers this to be of type any[], which is almost never a good thing ...
Type inference
- How can we see what TypeScript infers?
Just hover over the variable in VS Code! - ⚠️ If we use
constto initialize a variable,
TypeScript will infer it as a literal type

Higher-order functions
- We talked about type annotation of functions,
but what about higher-order functions?-
Uh... what is a higher-order function?
- MDN
-
Uh... what is a higher-order function?

Higher-order functions
// We know how to annotate the sum function in TypeScript
function sum(a, b) {
return a + b;
}
// But how do we annotate the add function?
function add(a) {
return function(b) {
return sum(a, b);
}
}
const addSeven = add(7);
console.log(addSeven(3));
// 10
Higher-order functions
// Solution to the previous slide:
function sum(a: number, b: number): number {
return a + b;
}
function add(a: number): (b: number) => number {
return function(b: number) {
return sum(a, b);
}
}
const addSeven = add(7);
console.log(addSeven(3));
// 10
First-class functions
/* JavaScript has first-class functions, so we can encounter them anywhere
e.g. in React props
Exercise: copy-paste this in the TypeScript playground
and add the missing interface */
interface Props {
// ?
}
const props: Props = {
onClick: () => console.log("Hi there!"),
onSave: (data: string) => doSomethingWithDataAndReturnBoolean(data)
}
function doSomethingWithDataAndReturnBoolean(data: string): boolean {
// This is just a mock implementation ...
return true;
}
First-class functions
// Solution to the previous slide
interface Props {
onClick: () => void;
onSave: (data: string) => boolean
}
const props: Props = {
onClick: () => console.log("Hi there!"),
onSave: (data: string) => doSomethingWithDataAndReturnBoolean(data)
}
function doSomethingWithDataAndReturnBoolean(data: string): boolean {
// This is just a mock implementation ...
return true;
}
any
- any turns off type checking completely
- Not recommended without good reason
- Code smell
let greeting: any = [];
// Since we annotated greeting with any, we can change the type later on
// to anything else: string, number, boolean, array, object ...
// We can also call any method on it, or access any property,
// even if that method or property does not exist
greeting.say();
greeting.toUpperCase();
// At compile time everything is OK. At run time, this will cause an error.
unknown
let vAny: any = 10; // We can assign anything to any
let vUnknown: unknown = 10; // We can assign anything to unknown just like any
let s1: string = vAny; // Any is assignable to anything
let s2: string = vUnknown; // Invalid; we can't assign vUnknown to any other type
vAny.method(); // Ok; anything goes with any
vUnknown.method(); // Not ok; we don't know anything about this variable
// Source: https://stackoverflow.com/a/51439876
unknown
- Useful when accepting multiple types as arguments
- Better than any ...
function prettyPrint(x: unknown): string {
if (Array.isArray(x)) {
return "[" + x.map(prettyPrint).join(", ") + "]";
}
if (typeof x === "string") {
return `"${x}"`;
}
if (typeof x === "number") {
return String(x);
}
return "etc.";
}
// Source: https://blog.logrocket.com/when-to-use-never-unknown-typescript
Asynchronous code
// What is the return type of the function below?
async function getSomeData() {
return fetch("https://some-data.com/api/data");
}
Asynchronous code
// Answer to question on the previous slide
async function getSomeData(): Promise<Response> {
return fetch("https://some-data.com/api/data");
}TypeScript comes with a ton of built-in types
e.g. for promises, events ...

Asynchronous code
// What will be the return type of the function below?
function getSomePromise() {
return new Promise(() => {
return getRandomNumber();
});
}
function getRandomNumber(): number {
return Math.random();
}
Asynchronous code
/* If we don't pass a type to the generic Promise constructor,
the Typescript compiler will infer it as Promise<unknown>.
The compiler is flawed here: it can't infer the Promise type (number).
*/
function getSomePromise(): Promise<unknown> {
return new Promise(() => {
return getRandomNumber();
});
}
function getRandomNumber(): number {
return Math.random();
}
Asynchronous code
/*
But if we help the Typescript compiler out,
it can infer it as Promise<number>
*/
function getSomePromise() {
return new Promise<number>(() => {
return getRandomNumber();
});
}
function getRandomNumber(): number {
return Math.random();
}

Extra
- Wil je TypeScript ten volle begrijpen?
Leer en lees dan zelf over volgende topics:

Extra
- Wil je TypeScript ten volle begrijpen?
Leer en lees dan zelf over volgende topics:
TypeScript
TypeScript with React/Next.js


TypeScript + React/Next.js
- You're an expert at TypeScript now. Great!
- But how do you use it with React/Next.js?
-
React
- Props
- Hooks
- Events
- Children
- Styles
-
React

TypeScript + React/Next.js
- You're an expert at TypeScript now. Great!
- But how do you use it with React/Next.js?
-
React
- More advanced cases?
Check out React TypeScript cheatsheet!
- More advanced cases?
-
React

TypeScript + React/Next.js
- You're an expert at TypeScript now. Great!
- But how do you use it with React/Next.js?
- Next.js:
- All that applies to React
- VS Code plugin
- Object Relational Mapper (ORM)
- Next.js:

TypeScript + React/Next.js
function Button({ label, handleClick }) {
return <button className="btn btn-large whatever" onClick={handleClick}>{label}</button>;
}-
Exercise:
- Create a new React project (with Vite)
- Add and use TypeScript (documentation)
- Create the component above and use it in App
- Add type annotations for the props

TypeScript + React/Next.js
interface Props {
label: string;
handleClick: () => number;
}
function Button({ label, handleClick }: Props) {
return <button className="btn btn-large whatever" onClick={handleClick}>
{label}
</button>;
}
export default Button;PGM5/1 - TypeScript
By kareldesmet
PGM5/1 - TypeScript
- 165