Skip to content

Typescript Code Conventions

Bij het programmeren in TypeScript is het belangrijk dat je broncode leesbaar en begrijpelijk is. Als we ons allemaal aan dezelfde afspraken houden, wordt het makkelijker code te schrijven en onderhouden en ook om daarbij als team samen te werken. We maken daarom gebruik van de “Hogeschool van Amsterdam Code Conventions”, beschreven op deze pagina.

Inhoudsopgave

Naamgeving

Gebruik zelf beschrijvende variabel namen

De naam van een variabel, functie of klasse hoort altijd zelf beschrijvend te zijn over waarom het bestaat, wat het doet, en hoe het wordt gebruikt. Gebruik daarom duidelijke namen die zich onderscheiden van overige namen, zodat de lezer weet wat de verschillen zijn.

Dus niet:

function isBetween(a1: number, a2: number, a3: number): boolean {
  return a2 <= a1 && a1 <= a3;
}

Maar:

function isBetween(value: number, left: number, right: number): boolean {
  return left <= value && value <= right;
}

Gebruik uitspreekbare namen voor variabelen

Wat hierbij ook belangrijk is, is het gebruik van uitspreekbare namen. Dit maakt het vragen om hulp of feedback wat eenvoudiger voor de ander.

Dus niet:

class Subs {
    public ccId: number;
    public billingAddrId: number;
    public shippingAddrId: number;
}

Maar:

class Subscription {
    public creditCardId: number;
    public billingAddressId: number;
    public shippingAddressId: number;
}

Voeg geen onnodige context toe

Als de naam van een klasse/type/object iets vertelt, hoef je dit niet te herhalen in je variabel naam.

Dus niet:

type Car = {
    carMake: string;
    carModel: string;
    carColor: string;
};

function print(car: Car): void {
    console.log(`${car.carMake} ${car.carModel} (${car.carColor})`);
}

Maar:

type Car = {
    make: string;
    model: string;
    color: string;
};

function print(car: Car): void {
    console.log(`${car.make} ${car.model} (${car.color})`);
}

Naamgeving Conventies

TypeScript kent twee vormen van naming conventions. Dit zijn:

  • camelCase
  • PascalCase

Gebruik van camelCase

camelCase gebruiken we voor de naamgeving van variabelen en functies. Ook voor typescript bestandsnamen gebruiken we camelCase.

Dus niet:

const FooBar;
function BarFunc() {}

Maar:

const fooBar;
function barFunc() {}

Ook gebruiken we camelCase voor leden van een klasse of interface, methoden en methodenparameters.

Dus niet:

class Foo {
    Bar: number;
    BarFunction() {}
}

Maar:

class Foo {
    bar: number;
    barFunction() {}
}

Gebruik van PascalCase

PascalCase gebruiken we voor de naamgeving van klassen en interfaces

Dus niet:

class foo {}

Maar:

class Foo {}

Voor enums gebruiken we PascalCase, en voor de enum leden gebruiken we camelCase

Dus niet:

enum notificationTypes {
    Default = 0,
    Info = 1,
    Success = 2,
    Error = 3,
}

Maar:

enum NotificationTypes {
    default = 0,
    info = 1,
    success = 2,
    error = 3,
}

Naamgeving van Booleans

Gebruik geen negatieve namen voor boolean variabelen

Dus niet:

const isNotEnabled = true;

Maar:

const isEnabled = false;

Een prefix zoals: is, are of has helpt elke ontwikkelaar binnen je team om het verschil te zien tussen een overig variabel en een boolean variabel.

Dus niet:

const enabled = false;

Maar:

const isEnabled = false;

Code commentaar

Wat wij voorop willen stellen voor code commentaar is dat je het niet moet schrijven omdat het maar moet. Neem de tijd en schrijf het zo goed als je kan op plekken waar het meerwaarde biedt voor jou of je teamleden. Dit maakt het voor je mede-programmeurs en docenten een stuk aangenamer om met je code aan te slag gaan.

Maak goed gebruik van commentaar

Commentaar voeg je toe om de werking van de code toe te lichten. Hierbij is het van groot belang om te beschrijven waarom die code is toegevoegd, en niet wat de code doet.

Dit kan handig zijn op plekken waar:

  • Wordt omgegaan met uitzonderingen
  • Een complexe berekening wordt gedaan
  • Een niet-intuïtieve handeling wordt uitgevoerd

Dus niet:

// Calculate amount of rows left in table
const rowsLeft: number = 6 - dataPayment.length;

Maar:

// We always want at least 6 table rows to keep the UI in place
const rowsLeft: number = 6 - dataPayment.length;

Schrijf geen commentaar als het geen informatie toevoegt

Soms is commentaar niet nodig omdat de code al genoeg vertelt.

Dus niet:

// Redirect to app index
window.location.href = "../app/";

Dus niet:

// Clear the existing table content
paymentTable.innerHTML = "";

Als je twijfelt of code overbodig is, lees de code goed na en denk bij jezelf: zou iemand buiten dit project begrijpen wat hier gebeurt?

Commentaar conventies

  • Schrijf commentaar in het Engels
  • Begin je commentaar met een spatie
  • Voeg geen leeg commentaar toe in je code
  • Geen witregel tussen commentaar en een uitdrukking

Dus niet:

//Hier voegen we per betaling een rij toe aan de tabel

dataPayment.forEach((payment) => {});

Maar:

// Generate new row for each payment
dataPayment.forEach((payment) => {});

Multiline docstrings

Bij functies staat het doel van de functie, de mee te geven argumenten én de return value beschreven in een docstring. Een docstring is een blok commentaar over meerdere regels. Ook deze worden geschreven in het Engels. In Typescript ziet dit er als volgt uit :

Voorbeeld docstring

/*
Get a specific key from the session. If you need multiple keys from the session, it's better to use {@link getAll} instead.  

@key - Name of the key to get  
@param [defaultValue] - Value to return if the key does not exist or   returns empty. (Default: `undefined`)  
@returns Returns the value of the key, or the specified default value  
*/
export function get(key: string, defaultValue: any = undefined): any {
//Instead of copying the whole session, just copy the requested key, if it exists.
if (session[key]) {
    const copy = copyObject({
    temp: session[key],
    });

    return copy.temp;
}

return defaultValue;
}

Algemene styling

Inspringing

Gebruikt altijd vier spaties en geen tab om in te springen. Dit kan je instellen in je IDE.

Brackets

Voorbeeld correct formatting van haakjes.

Dus niet:

// Dit is een voorbeeld hoe het niet moet!
export function get(key: string, defaultValue: any = undefined): any 
{
    if (session[key]){
    const copy = copyObject({
        temp: session[key],});

    return copy.temp;

    }

    return defaultValue;
}

Maar:

export function get(key: string, defaultValue: any = undefined): any {
    if (session[key]) {
    const copy = copyObject({
        temp: session[key],
    });

    return copy.temp;
    }

    return defaultValue;
}

Semicolons

In de bovenstaande voorbeelden is te zien dat elke regel die een statement bevat wordt geëindigd met een punt-komma (semi-column).