In het huidige snel veranderende digitale landschap is JavaScript de meest gebruikte taal voor het bouwen van dynamische webapplicaties. De dynamische typing van JavaScript kan echter soms leiden tot subtiele fouten, waardoor het een uitdaging is om ze vroeg in het ontwikkelproces te ontdekken.

Dat is waar TypeScript om de hoek komt kijken – om de manier waarop we JavaScript code schrijven te revolutioneren.

In dit artikel nemen we een diepe duik in de wereld van TypeScript en verkennen we de mogelijkheden, voordelen en best practices ervan. Je leert ook hoe TypeScript de beperkingen van JavaScript aanpakt en de kracht van statische typing mogelijk maakt bij het bouwen van robuuste en schaalbare webapplicaties.

Laten we snel beginnen!

Wat is TypeScript?

TypeScript is een superset van JavaScript die optionele statische typing en geavanceerde mogelijkheden toevoegt aan JavaScript. Het is ontwikkeld door Microsoft en werd voor het eerst uitgebracht in oktober 2012. Sinds de lancering in 2012 heeft het snel aan populariteit gewonnen in de webdevelopmentcommunity.

Volgens het Stack Overflow onderzoek onder developers uit 2022 kwam TypeScript met 73,46% naar voren als de 4e meest geliefde technologie. TypeScript werd gemaakt om enkele van de beperkingen van JavaScript aan te pakken, zoals het gebrek aan strong typing, wat kan leiden tot subtiele fouten die moeilijk te ontdekken zijn tijdens het ontwikkelingsproces.

Neem bijvoorbeeld de volgende JavaScript code:

function add(a, b) {
  return a + b;
}

let result = add(10, "20"); // No error, but result is "1020" instead of 30

De bovenstaande code maakt een functie add, die dynamisch getyped is. Het type van de argumenten a en b wordt niet afgedwongen. Daardoor levert het doorgeven van een string in plaats van een getal als argument geen fout op, maar worden de waarden als string aan elkaar gekoppeld, wat leidt tot onverwacht gedrag.

Met TypeScript wordt optionele statische typing geïntroduceerd, waardoor developers de typen van variabelen, functie parameters en return waarden kunnen specificeren, en type-gerelateerde fouten tijdens de ontwikkeling kunnen opvangen.

function add(a: number, b: number): number {
  return a + b;
}

let result = add(10, "20"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'

In de TypeScript code hierboven zijn de types van de parameters a en b expliciet gedefinieerd als getallen. Als een string als argument wordt doorgegeven, geeft TypeScript een compileerfout, waardoor vroegtijdig feedback wordt gegeven om mogelijke problemen op te vangen.

Eigenschappen van TypeScript

TypeScript biedt verschillende krachtige features voor moderne webontwikkeling die enkele van de beperkingen van JavaScript aanpakken. Deze eigenschappen bieden een verbeterde ontwikkelaarservaring en code-organisatie. Denk hierbij aan:

1. Statische typing

TypeScript heeft een sterk typingssysteem waarmee de types van variabelen en functieparameters tijdens het compileren kunnen worden gespecificeerd. Dit maakt vroege opsporing van type-gerelateerde fouten mogelijk, waardoor de code betrouwbaarder wordt en minder vatbaar voor bugs.

In JavaScript daarentegen zijn variabelen dynamisch getyped, wat betekent dat hun type tijdens runtime kan veranderen.

De JavaScript code hieronder toont bijvoorbeeld de declaratie van twee variabelen die dynamisch getyped zijn als getal en string:

let num1 = 10; // num1 is dynamically typed as a number
let num2 = "20"; // num2 is dynamically typed as a string

let result = num1 + num2; // No error at compile-time
console.log(result); // Output: "1020"

Deze bovenstaande code geeft “1020” weer, een aaneenschakeling van getal en tekenreeks. Dit is niet de verwachte output – wat betekent dat dit je code kan beïnvloeden. Het nadeel van JavaScript is dat het geen foutmelding geeft. Met TypeScript kun je dit oplossen door de types van elke variabele te specificeren:

let num1: number = 10; // num1 is statically typed as a number
let num2: string = "20"; // num2 is statically typed as a string

let result = num1 + num2; // Error: Type 'string' is not assignable to type 'number'

In de bovenstaande code levert een poging om een getal en een string aan elkaar te rijgen met de operator + een compile time error op, omdat TypeScript strikte typecontrol afdwingt.

Dit helpt potentiële type-gerelateerde bugs op te sporen voordat de code wordt uitgevoerd, wat leidt tot meer robuuste en foutloze code.

2. Optionele typing

TypeScript biedt flexibiliteit bij het al dan niet gebruiken van statische typing. Dit betekent dat je kunt kiezen om types te specificeren voor variabelen en functieparameters, of TypeScript de types automatisch laat afleiden op basis van de toegekende waarde.

Bijvoorbeeld:

let num1: number = 10; // num1 is statically typed as a number
let num2 = "20"; // num2 is dynamically typed as a string

let result = num1 + num2; // Error: Operator '+' cannot be applied to types 'number' and 'string'

In deze code wordt het type van num2 afgeleid als string op basis van de toegekende waarde, maar je kunt ervoor kiezen om het type desgewenst op te geven.

Je kunt het type ook instellen op any, wat betekent dat het elk type waarde accepteert:

let num1: number = 10;
let num2: any = "20";

let result = num1 + num2; // Error: Operator '+' cannot be applied to types 'number' and 'string'

3. ES6+ functies

TypeScript ondersteunt moderne JavaScript features, waaronder degene die zijn geïntroduceerd in ECMAScript 6 (ES6) en latere versies.

Hierdoor kunnen developers strakkere en expressievere code schrijven met functies als arrow functies, destructurering, template literals en meer, met toegevoegde typecontrol.

Bijvoorbeeld:

const greeting = (name: string): string => {
  return `Hello, ${name}!`; // Use of arrow function and template literal
};

console.log(greeting("John")); // Output: Hello, John!

In deze code worden de arrow functie en template literal perfect gebruikt. Hetzelfde geldt voor alle JavaScript syntaxis.

4. Codeorganisatie

In JavaScript kan het organiseren van code in aparte bestanden en het beheren van dependencies een uitdaging worden naarmate de codebase groeit. TypeScript biedt echter ingebouwde ondersteuning voor modules en namespaces om code beter te organiseren.

Modules zorgen voor inkapseling van code in afzonderlijke bestanden, waardoor het gemakkelijker wordt om grote codebases te beheren en te onderhouden.

Hier is een voorbeeld:

// greeting.ts:
export function greet(name: string): string { // Export a function from a module
  return `Hello, ${name}!`;
}

// app.ts:
import { greet } from "./greeting"; // Import from a module

console.log(greet("John")); // Output: Hello, John!

In het bovenstaande voorbeeld hebben we twee aparte bestanden greeting.ts en app.ts. Het app.ts bestand importeert de greet functie uit het greeting.ts bestand met behulp van het import statement. Het greet.ts bestand exporteert de greet functie met behulp van het export keyword, waardoor het toegankelijk wordt voor import in andere bestanden.

Dit zorgt voor een betere organisatie van de code en scheiding van zorgen, waardoor het beheren en onderhouden van grote codebases gemakkelijker wordt.

Namespaces in TypeScript bieden een manier om gerelateerde code te groeperen en globale namespace vervuiling te voorkomen. Ze kunnen worden gebruikt om een container te definiëren voor een verzameling gerelateerde klassen, interfaces, functies of variabelen.

Hier is een voorbeeld:

namespace Utilities {
  export function greet(name: string): string {
    return `Hello, ${name}!`;
  }
  
  export function capitalize(str: string): string {
    return str.toUpperCase();
  }
}

console.log(Utilities.greet("John")); // Output: Hello, John!
console.log(Utilities.capitalize("hello")); // Output: HELLO

In deze code definiëren we een namespace Utilities die twee functies bevat, greet en capitalize. We kunnen deze functies gebruiken met de naam van de namespace gevolgd door de naam van de functie, waardoor een logische groepering ontstaat voor gerelateerde code.

5. Object oriented programming functies (OOP)

TypeScript ondersteunt OOP concepten zoals klassen, interfaces en inheriting, waardoor gestructureerde en georganiseerde code mogelijk is.

Bijvoorbeeld:

class Person {
  constructor(public name: string) {} // Define a class with a constructor
  greet(): string { // Define a method in a class
    return `Hello, my name is ${this.name}!`;
  }
}

const john = new Person("John"); // Create an instance of the class
console.log(john.greet()); // Output: Hello, my name is John!

6. Geavanceerd typesysteem

TypeScript biedt een geavanceerd typesysteem dat generics, unions, intersecties en meer ondersteunt. Deze eigenschappen verbeteren de statische typecontrol van TypeScript, waardoor developers robuustere en expressievere code kunnen schrijven.

Generics: Generics maken het mogelijk herbruikbare code te schrijven die met verschillende typen kan werken. Generics zijn als placeholders voor types die tijdens de runtime worden bepaald op basis van de waarden die aan een functie of klasse worden doorgegeven.

Laten we bijvoorbeeld een generic functie met de naam identity definiëren die een argumentwaarde neemt van het type T en een waarde teruggeeft van hetzelfde type T:

function identity(value: T): T {
  return value;
}

let num: number = identity(10); // T is inferred as number
let str: string = identity("hello"); // T is inferred as string

In het bovenstaande voorbeeld wordt het type T afgeleid op basis van het type waarde dat aan de functie wordt doorgegeven. In het eerste gebruik van de identity functie wordt T afgeleid als getal omdat we 10 als argument doorgeven, en in het tweede gebruik wordt T afgeleid als string omdat we "hello" als argument doorgeven.

Unions en intersections: Unions en intersections worden gebruikt om typen samen te stellen en complexere type-relaties te maken.

Unions maken het mogelijk om twee of meer types te combineren tot een enkel type dat elk van de gecombineerde types kan hebben. Met intersections kunnen twee of meer typen worden gecombineerd tot een enkel type dat moet voldoen aan alle gecombineerde typen.

We kunnen bijvoorbeeld twee typen Employee en Manager definiëren, die respectievelijk een employee en een manager voorstellen.

type Employee = { name: string, role: string };
type Manager = { name: string, department: string };

Met behulp van de types Employee en Manager kunnen we een union type EmployeeOrManager definiëren dat ofwel een Employee ofwel een Manager kan zijn.

type EmployeeOrManager = Employee | Manager; // Union type

let person1: EmployeeOrManager = { name: "John", role: "Developer" }; // Can be either Employee or Manager

In bovenstaande code is de variabele person1 van het type EmployeeOrManager, wat betekent dat er een object aan toegewezen kan worden dat voldoet aan het type Employee of Manager.

We kunnen ook een intersection type EmployeeOrManager definiëren dat moet voldoen aan de typen Employee en Manager.

type EmployeeAndManager = Employee & Manager; // Intersection type

let person2: EmployeeAndManager = { name: "Jane", role: "Manager", department: "HR" }; // Must be both Employee and Manager

In bovenstaande code is de variabele person2 van het type EmployeeAndManager, wat betekent dat het een object moet zijn dat voldoet aan de typen Employee en Manager.

7. Compatibiliteit met JavaScript

TypeScript is ontworpen als superset van JavaScript, wat betekent dat alle geldige JavaScript code ook geldige TypeScript code is. Dit maakt het integreren van TypeScript in bestaande JavaScript projecten eenvoudig zonder alle code te hoeven herschrijven.

TypeScript bouwt voort op JavaScript en voegt optionele statische typing en extra mogelijkheden toe, maar je kunt nog steeds gewone JavaScript code gebruiken.

Als je bijvoorbeeld een bestaand JavaScript bestand genaamd  app.js hebt, kun je dat hernoemen naar app.ts en geleidelijk TypeScript functies gaan gebruiken zonder de bestaande JavaScript code te veranderen. TypeScript zal de JavaScript code nog steeds kunnen begrijpen en compileren als geldige TypeScript.

Hier is een voorbeeld van hoe TypeScript naadloze integratie biedt met JavaScript:

// app.js - Existing JavaScript code
function greet(name) {
  return "Hello, " + name + "!";
}

console.log(greet("John")); // Output: Hello, John!

Je kunt het bovenstaande JavaScript bestand hernoemen naar app.ts en TypeScript functies gaan gebruiken:

// app.ts - Same JavaScript code as TypeScript
function greet(name: string): string {
  return "Hello, " + name + "!";
}

console.log(greet("John")); // Output: Hello, John!

In het bovenstaande voorbeeld voegen we een type annotatie toe aan de name parameter, die we specificeren als string, wat optioneel is in TypeScript. De rest van de code blijft hetzelfde als JavaScript. TypeScript is in staat de JavaScript code te begrijpen en typecontrol te bieden voor de toegevoegde type-annotatie, waardoor het gemakkelijk is TypeScript geleidelijk over te nemen in een bestaand JavaScript project.

Aan de slag met TypeScript

TypeScript is een officiële compiler die je met npm in je project kunt installeren. Als je TypeScript 5.0 in je project wilt gaan gebruiken, kun je het volgende commando uitvoeren in de map van je project:

npm install -D typescript

Dit zal de compiler installeren in de map node_modules, die je nu kunt uitvoeren met het commando npx tsc.

Voor je JavaScript project moet je eerst een node project initialiseren met het volgende commando om een package.json bestand aan te maken:

npm init -y

Vervolgens kun je de TypeScript dependencies installeren, TypeScript bestanden aanmaken met de .ts extensie en je TypeScript code schrijven.

Zodra je je TypeScript code hebt geschreven, moet je die compileren naar JavaScript met de TypeScript compiler (tsc). Je kunt het volgende commando uitvoeren in je projectmap:

npx tsc .ts

Dit compileert de TypeScript code in het opgegeven bestand naar JavaScript en genereert een .js bestand met dezelfde naam.

Je kunt dan de gecompileerde JavaScript code in je project uitvoeren, net zoals je gewone JavaScript code zou uitvoeren. Je kunt Node.js gebruiken om de JavaScript code uit te voeren in een Node.js omgeving of het gecompileerde JavaScript bestand opnemen in een HTML bestand en het uitvoeren in een browser.

Werken met interfaces

Interfaces in TypeScript worden gebruikt om contracten of vormen van objecten te definiëren. Ze stellen je in staat de structuur of vorm te specificeren waaraan een object moet voldoen.

Interfaces definiëren een verzameling properties en/of methoden die een object moet hebben om als compatibel met de interface beschouwd te worden. Interfaces kunnen worden gebruikt om type-annotaties te geven voor objecten, functieparameters en retourwaarden, waardoor betere statische typecontrol en suggesties voor code-aanvulling in IDE’s mogelijk zijn.

Hier is een voorbeeld van een interface in TypeScript:

interface Person {
  firstName: string;
  lastName: string;
  age: number;
}

In dit voorbeeld definiëren we een interface Person die drie properties specificeert: firstName van het type string, lastName van het type string, en age van het type number.

Elk object dat deze drie properties heeft met de gespecificeerde types wordt beschouwd als compatibel met de interface Person. Laten we nu objecten definiëren die voldoen aan de interface Person:

let person1: Person = {
  firstName: "John",
  lastName: "Doe",
  age: 30
};

let person2: Person = {
  firstName: "Jane",
  lastName: "Doe",
  age: 25
};

In dit voorbeeld maken we twee objecten person1 en person2 die voldoen aan de interface Person. Beide objecten hebben de vereiste dependencies firstName, lastName, en age met de gespecificeerde types, zodat ze compatibel zijn met de interface Person.

Interfaces uitbreiden

Interfaces kunnen ook worden uitgebreid om nieuwe interfaces te maken die dependencies inheriten van bestaande interfaces.

Bijvoorbeeld:

interface Animal {
  name: string;
  sound: string;
}

interface Dog extends Animal {
  breed: string;
}

let dog: Dog = {
  name: "Buddy",
  sound: "Woof",
  breed: "Labrador"
};

In dit voorbeeld definiëren we een interface Animal met dependencies name en sound, en vervolgens definiëren we een nieuwe interface “Dog” die de interface Animal uitbreidt en een nieuwe properties breed toevoegt. De interface Dog inherit de properties van de interface Animal, dus elk object dat voldoet aan de interface Dog moet ook de properties name en sound hebben.

Optionele properties

Interfaces kunnen ook optionele properties hebben, die worden aangeduid met een ? na de naam van de properties.

Hier is een voorbeeld:

interface Car {
  make: string;
  model: string;
  year?: number;
}

let car1: Car = {
  make: "Toyota",
  model: "Camry"
};

let car2: Car = {
  make: "Honda",
  model: "Accord",
  year: 2020
};

In dit voorbeeld definiëren we een interface Car met properties make en model, en een optionele properties year. De property year is niet vereist, dus objecten die voldoen aan de interface Car kunnen die al dan niet hebben.

Geavanceerde typecontrol

TypeScript biedt ook geavanceerde opties voor typecontrol in tsconfig.json. Deze opties kunnen de typecontrol mogelijkheden van je TypeScript project verbeteren en potentiële fouten tijdens het compileren opvangen, wat leidt tot meer robuuste en betrouwbare code.

1. strictNullChecks

Indien ingesteld op true dwingt TypeScript strikte nulcontrols af, wat betekent dat variabelen geen waarde kunnen hebben van null of undefined tenzij expliciet gespecificeerd met het union type null of undefined.

Bijvoorbeeld:

{
  "compilerOptions": {
    "strictNullChecks": true
  }
}

Met deze optie ingeschakeld vangt TypeScript potentiële null of undefined waarden op tijdens het compileren, waardoor runtime fouten door toegang tot properties of methoden op null of undefined variabelen worden voorkomen.

// Example 1: Error - Object is possibly 'null'
let obj1: { prop: string } = null;
console.log(obj1.prop);

// Example 2: Error - Object is possibly 'undefined'
let obj2: { prop: string } = undefined;
console.log(obj2.prop);

2. strictFunctionTypes

Indien ingesteld op true maakt TypeScript strikte control van functietypen mogelijk, inclusief functieparameter bivariantie, die ervoor zorgt dat functieargumenten strikt gecontrolerd worden op typecompatibiliteit.

Bijvoorbeeld:

{
  "compilerOptions": {
    "strictFunctionTypes": true
  }
}

Met deze optie ingeschakeld, vangt TypeScript potentiële functieparameter mismatches op tijdens het compileren, wat helpt om runtime fouten te voorkomen veroorzaakt door het doorgeven van onjuiste argumenten aan functies.

// Example: Error - Argument of type 'number' is not assignable to parameter of type 'string'
function greet(name: string) {
  console.log(`Hello, ${name}!`);
}

greet(123);

3. noImplicitThis

Indien ingesteld op true, verbiedt TypeScript het gebruik van this met een implicit any type, wat helpt om potentiële fouten op te vangen bij het gebruik van this in klassemethoden.

Bijvoorbeeld:

{
  "compilerOptions": {
    "noImplicitThis": true
  }
}

Met deze optie ingeschakeld zal TypeScript potentiële fouten opvangen die veroorzaakt worden door het gebruik van this zonder de juiste type annotaties of binding in klassemethoden.

// Example: Error - The 'this' context of type 'void' is not assignable to method's 'this' of type 'MyClass'
class MyClass {
  private prop: string;

  constructor(prop: string) {
    this.prop = prop;
  }

  printProp() {
    console.log(this.prop);
  }
}

let obj = new MyClass("Hello");
setTimeout(obj.printProp, 1000); // 'this' context is lost, potential error

4. target

De optie target bepaalt de ECMAScript doelversie voor je TypeScript code. Het bepaalt de versie van JavaScript die de TypeScript compiler als uitvoer moet genereren.

Bijvoorbeeld:

{
  "compilerOptions": {
    "target": "ES2018"
  }
}

Met deze optie ingesteld op“ES2018” zal TypeScript JavaScript code genereren die voldoet aan de ECMAScript 2018 standaard.

Dit kan handig zijn als je wilt profiteren van de nieuwste JavaScript functies en -syntaxis, maar ook achterwaartse compatibiliteit met oudere JavaScript omgevingen moet waarborgen.

5. module

De optie module specificeert het modulesysteem dat in je TypeScript code moet worden gebruikt. Veel voorkomende opties zijn “CommonJS“,”AMD“,”ES6“,”ES2015“, enz. Dit bepaalt hoe je TypeScript modules worden gecompileerd in JavaScript modules.

Bijvoorbeeld:

{
  "compilerOptions": {
    "module": "ES6"
  }
}

Met deze optie ingesteld op “ES6” zal TypeScript JavaScript code genereren die ECMAScript 6-module-syntax gebruikt.

Dit kan handig zijn als je werkt met een moderne JavaScript omgeving die ECMAScript 6 modules ondersteunt, zoals in een front-end applicatie die een module bundler zoals webpack of Rollup gebruikt.

6. noUnusedLocals en noUnusedParameters

Met deze opties kan TypeScript respectievelijk ongebruikte lokale variabelen en functieparameters opvangen.

Indien ingesteld op true, zal TypeScript compilatiefouten geven voor alle lokale variabelen of functieparameters die worden gedeclared maar niet gebruikt in de code.

Bijvoorbeeld:

{
  "compilerOptions": {
    "noUnusedLocals": true,
    "noUnusedParameters": true
  }
}

Dit zijn nog maar een paar voorbeelden van geavanceerde typecontrol opties in TypeScript’s tsconfig.json bestand. Je kunt de officiële documentatie raadplegen voor meer.

Best practices en tips voor het gebruik van TypeScript

1. Annoteer de types goed voor variabelen, functie parameters en return waarden

Een van de belangrijkste voordelen van TypeScript is het sterke typingssysteem, waarmee je expliciet de types van variabelen, functieparameters en return waarden kunt specificeren.

Dit verbetert de leesbaarheid van code, vangt mogelijke typefouten vroegtijdig op, en maakt intelligente code-aanvulling in IDE’s mogelijk.

Hier is een voorbeeld:

// Properly annotating variable types
let age: number = 25;
let name: string = "John";
let isStudent: boolean = false;
let scores: number[] = [98, 76, 89];
let person: { name: string, age: number } = { name: "John", age: 25 };

// Properly annotating function parameter and return types
function greet(name: string): string {
  return "Hello, " + name;
}

function add(a: number, b: number): number {
  return a + b;
}

2. Gebruik de geavanceerde typemogelijkheden van TypeScript effectief

TypeScript heeft een rijke verzameling geavanceerde typemogelijkheden, zoals generics, unions, intersections, conditionele types en mapped types. Deze properties kunnen je helpen om meer flexibele en herbruikbare code te schrijven.

Hier is een voorbeeld:

// Using generics to create a reusable function
function identity(value: T): T {
  return value;
}

let num: number = identity(42); // inferred type: number
let str: string = identity("hello"); // inferred type: string

// Using union types to allow multiple types
function display(value: number | string): void {
  console.log(value);
}

display(42); // valid
display("hello"); // valid
display(true); // error

3. Schrijf onderhoudbare en schaalbare code met TypeScript

TypeScript bevordert het schrijven van onderhoudbare en schaalbare code door mogelijkheden als interfaces, klassen en modules.

Hier is een voorbeeld:

// Using interfaces for defining contracts
interface Person {
  name: string;
  age: number;
}

function greet(person: Person): string {
  return "Hello, " + person.name;
}

let john: Person = { name: "John", age: 25 };
console.log(greet(john)); // "Hello, John"

// Using classes for encapsulation and abstraction
class Animal {
  constructor(private name: string, private species: string) {}

  public makeSound(): void {
    console.log("Animal is making a sound");
  }
}

class Dog extends Animal {
  constructor(name: string, breed: string) {
    super(name, "Dog");
    this.breed = breed;
  }

  public makeSound(): void {
    console.log("Dog is barking");
  }
}

let myDog: Dog = new Dog("Buddy", "Labrador");
myDog.makeSound(); // "Dog is barking"

4. Maak gebruik van TypeScript’s tools en IDE ondersteuning

TypeScript heeft uitstekende tools en IDE ondersteuning, met functies als autocompletie, type-inferentie, refactoring en foutcontrol.

Maak gebruik van deze functies om je productiviteit te verhogen en potentiële fouten vroeg in het ontwikkelingsproces op te sporen. Zorg ervoor dat je een TypeScript bewuste IDE gebruikt, zoals Visual Studio Code, en installeer de TypeScript plugin voor een betere codebewerkingservaring.

VS Code TypeScript uitbreiding
VS Code TypeScript uitbreiding

Samenvatting

TypeScript biedt een groot aantal krachtige mogelijkheden die je webontwikkelingsprojecten sterk kunnen verbeteren.

De sterke statische typing, geavanceerde typesysteem en objectgeoriënteerde programmeermogelijkheden maken het een waardevolle tool voor het schrijven van onderhoudbare, schaalbare en robuuste code. De tooling en IDE ondersteuning van TypeScript zorgen bovendien voor een naadloze ontwikkelervaring.

Als je TypeScript en zijn mogelijkheden wilt verkennen, kun je dat vandaag nog doen dankzij Kinsta’s Applicatie Hosting.