Achtergrond
Veel strikt getypeerde talen (C++, C#, Python) staan een expliciete beschrijving van operatoroverloads toe voor operators (zoals +, -, *, ==) op het niveau van de klasse. In TypeScript, net als in JavaScript, ontbreekt operatoroverloading op taalniveau vanwege historische en architectonische redenen.
Probleem
Wanneer ondersteuning voor wiskunde of andere operaties voor complexe types (zoals complexe getallen of vectoren) nodig is, is het onmogelijk om de standaardoperators te wijzigen. Dit beperkt de expressiviteit en vereist het uitvinden van alternatieve patronen.
Oplossing
In TypeScript wordt operatoroverloading nagebootst via speciaal genoemde methoden (zoals add, equals, multiply). Door de klasse uit te rusten met deze methoden realiseren we typeveilige gedrag, hoewel de syntaxis niet zo beknopt is als in C++.
Voorbeeldcode:
class Vector { constructor(public x: number, public y: number) {} add(other: Vector): Vector { return new Vector(this.x + other.x, this.y + other.y); } equals(other: Vector): boolean { return this.x === other.x && this.y === other.y; } } const a = new Vector(1, 2); const b = new Vector(3, 4); const c = a.add(b); // Vector { x: 4, y: 6 } const eq = a.equals(b); // false
Belangrijke kenmerken:
Is het mogelijk om het gedrag van de operator "==" of "+" te overschrijven voor een eigen klasse in TypeScript?
Nee, JavaScript (en TypeScript) staat niet toe om standaardoperators rechtstreeks te overbelasten voor gebruikersobjecten. Operators worden strikt toegepast volgens de standaard voor Object, Number en andere primitieve types. Elke poging tot dergelijke "overschrijving" zal leiden tot onjuiste of onverwachte gedragingen of werkt gewoon niet.
Kan men valueOf of toString gebruiken om indirect invloed uit te oefenen op de operators?
In bepaalde gevallen kan valueOf worden gebruikt (bijvoorbeeld voor een korte omzetting naar een getal), maar alleen voor operators die verwijzen naar de primitieve waarde van het object.
class Box { constructor(private v: number) {} valueOf() { return this.v; } } const a = new Box(10); console.log(a + 5); // 15 — werkt, maar voor complexe objecten niet intuïtief
Maar voor complexe structuren en logische operators is het zinvol om expliciete methoden te gebruiken.
Zijn er plannen om operatoroverloading toe te voegen aan TypeScript of ECMAScript?
Op dit moment zijn er geen goedgekeurde plannen: fundamenteel staat operatoroverloading haaks op het ontwerp van JS, omdat het het gedrag van standaardobjecten aanzienlijk kan veranderen en kan leiden tot instabiliteit in de code.
Een ontwikkelaar maakt een Matrix-klasse, waar hij valueOf/toString implementeert voor substitutie in wiskundige expressies. Bij optellingen met getallen of strings ontstaan onvoorspelbare resultaten, strikte typisatie is niet mogelijk.
Voordelen:
Nadelen:
De Vector-klasse implementeert methoden add, multiply, equals met duidelijke typisatie van invoer- en uitvoerparameters. Klanten van de klasse gebruiken expliciet de overeenkomstige methoden, de semantiek gaat niet verloren, en er is strikte typisatie verzekerd.
Voordelen:
Nadelen: