Geschiedenis van de vraag:
De in-operator is overgenomen door TypeScript uit JavaScript en wordt veel gebruikt voor het controleren van de aanwezigheid van een eigenschap in een object. In TypeScript krijgt de semantiek een extra betekenis vanwege het type-systeem — hier is het belangrijk niet alleen de aanwezigheid van een waarde te hebben, maar ook de declaratie op het type-niveau, vooral in gevallen van optionele eigenschappen.
Probleem:
Ontwikkelaars in TypeScript verwarren vaak een eenvoudige controle op undefined met de controle op de aanwezigheid van de eigenschap zelf in het object. Een fout kan optreden als de eigenschap bestaat, maar de waarde undefined is of als deze geërfd is in plaats van rechtstreeks op het object gedefinieerd.
Oplossing:
De in-operator controleert of de eigenschap daadwerkelijk aanwezig is in de prototypeketen van het object, ongeacht de waarde ervan. Dit speelt een belangrijke rol bij het controleren van optionele of berekende eigenschappen, waardoor onverwachte verwerking van falsy-waarden wordt voorkomen:
Codevoorbeeld:
interface User { id: number; name?: string; } const user1: User = { id: 1 }; const user2: User = { id: 2, name: undefined }; console.log('name' in user1); // false console.log('name' in user2); // true
Belangrijke kenmerken:
in-operator bepaalt de aanwezigheid van een eigenschap in het object of zijn prototype, niet alleen het bestaan van een waardeHoe verschilt het controleren op undefined (obj.prop !== undefined) van het gebruik van in?
De controle op undefined bepaalt alleen de waarde, maar niet de aanwezigheid van de eigenschap. Als de eigenschap er is, maar undefined is, is het resultaat true. Als de eigenschap helemaal niet bestaat, is de waarde ook undefined, maar semantisch zijn dit verschillende gevallen.
Voorbeeld:
const obj: any = { foo: undefined }; console.log('foo' in obj); // true console.log(obj.foo !== undefined); // false console.log('bar' in obj); // false console.log(obj.bar !== undefined); // false
Kan de in-operator alleen de aanwezigheid van de eigenschap op het object zelf controleren, terwijl de prototypeketen wordt genegeerd?
Nee, de standaard in controleert ook de prototypes. Voor alleen de eigen eigenschappen, gebruik de hasOwnProperty-methode:
const obj = Object.create({ foo: 123 }); obj.bar = 456; console.log('foo' in obj); // true console.log(obj.hasOwnProperty('foo')); // false
Kan je met de in-operator type narrowing uitvoeren voor union types in TypeScript?
Ja, in TypeScript lijkt in op Discriminated Union en stelt je in staat om het type te versmallen naar een specifieke variant:
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; size: number }; function getArea(shape: Shape) { if ('radius' in shape) { // Hier is shape een cirkel return Math.PI * shape.radius ** 2; } // Hier is shape een vierkant return shape.size ** 2; }
in-controle.in gebruiken voor een array (bij arrays retourneert het true voor numerieke indexen en geërfde eigenschappen).in te gebruiken voor niet-object waarden (zoals null of undefined).In een project met een array van gebruikers controleerden we een optioneel veld met user.name !== undefined, wat leidde tot onjuiste logica voor gebruikers wiens eigenschap expliciet was ingesteld op undefined.
Voordelen:
Nadelen:
We gebruikten in voor een nauwkeurige controle van de aanwezigheid van een optioneel gebruikersveld, ongeacht de waarde ervan, wat het mogelijk maakte om correct te onderscheiden tussen "geen veld" en "veld is aanwezig, maar waarde is niet ingesteld".
Voordelen:
Nadelen:
in-operator, wat niet altijd duidelijk is voor nieuwkomers