Historique de la question:
L'opérateur in a été hérité de JavaScript par TypeScript et est largement utilisé pour vérifier la présence d'une propriété dans un objet. En TypeScript, sa sémantique prend une signification supplémentaire en raison du système de types — il est important non seulement d'avoir une valeur, mais aussi de l'avoir déclarée au niveau du type, notamment dans les cas de propriétés optionnelles.
Problème:
Les développeurs de TypeScript confondent souvent la simple vérification sur undefined avec la vérification de la présence de la propriété elle-même dans l'objet. Une erreur peut survenir si la propriété existe, mais sa valeur est undefined ou si elle est héritée plutôt que définie directement sur l'objet.
Solution:
L'opérateur in vérifie si la propriété est réellement présente dans la chaîne de prototypes de l'objet, indépendamment de sa valeur. Cela joue un rôle important lors de la vérification de propriétés optionnelles ou calculées, ce qui permet d'éviter le traitement inattendu de valeurs falsy :
Exemple de code :
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
Caractéristiques clés :
in détermine la présence d'une propriété dans un objet ou son prototype, et non seulement l'existence d'une valeur.Quelle est la différence entre la vérification de undefined (obj.prop !== undefined) et l'utilisation de in ?
La vérification sur undefined détermine seulement la valeur, mais non la présence de la propriété. Si la propriété existe mais est undefined, le résultat sera true. Si la propriété n'existe pas du tout, sa valeur sera également undefined, mais sémantiquement, ce sont des cas différents.
Exemple :
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
L'opérateur in peut-il vérifier la présence d'une propriété uniquement sur l'objet lui-même, en ignorant la chaîne de prototypes ?
Non, l'opérateur in standard vérifie également les prototypes. Pour vérifier uniquement les propriétés propres, utilisez la méthode hasOwnProperty :
const obj = Object.create({ foo: 123 }); obj.bar = 456; console.log('foo' in obj); // true console.log(obj.hasOwnProperty('foo')); // false
Peut-on utiliser l'opérateur in pour le narrowing de types union en TypeScript ?
Oui, en TypeScript, in ressemble à un union discriminé et permet de réduire le type à une variante spécifique :
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; size: number }; function getArea(shape: Shape) { if ('radius' in shape) { // Ici shape est un cercle return Math.PI * shape.radius ** 2; } // Ici shape est un carré return shape.size ** 2; }
in.in pour les tableaux (sur les tableaux, retourne true pour les indices numériques et les propriétés héritées).in pour des valeurs autres que des objets (par exemple, null ou undefined).Dans un projet avec un tableau d'utilisateurs, on vérifiait un champ optionnel avec user.name !== undefined, ce qui entraînait une logique incorrecte pour les utilisateurs dont la propriété était explicitement définie comme undefined.
Avantages :
Inconvénients :
On utilisait in pour vérifier précisément la présence d'un champ optionnel chez l'utilisateur, indépendamment de sa valeur, ce qui a permis de différencier correctement "champ absent" et "champ présent mais valeur non spécifiée".
Avantages :
Inconvénients :
in, ce qui n'est pas toujours évident pour les débutants.