Maison > Questions et réponses > le corps du texte
P粉9577231242023-07-29 09:49:07
Vous avez raison, TypeScript ne vous permet pas d'accéder à des propriétés dont il ignore qu'elles peuvent exister sur le type de variable. Si le type est un type union, la propriété doit exister sur tous les membres du type union avant que TypeScript vous permette d'y accéder.
Mais il existe différentes manières de affiner le type de variables. Par exemple, vous pouvez d'abord vérifier si la valeur est vraie, et sinon, TypeScript limitera le type d'union à une simple ValidationError.
Normalement, une autre option consiste à utiliser l'opérateur in, mais dans ce cas, le type union contient plus que de simples types d'objets, donc TypeScript ne le permet pas.
Vous pouvez également définir un type de garde personnalisé (ou utiliser celui fourni par la bibliothèque, s'il en existe un), mais pour ce cas simple, il semble que cela puisse être un peu trop de travail pour ce que vous voulez.
Il existe d'autres façons de réduire les types, comme détaillé dans la documentation TypeScript que j'ai fournie. Comme vous l'avez mentionné, vérifier le résultat de l'opérateur typeof est également l'une des méthodes.
Cet exemple déclare uniquement qu'un type guard existe, plutôt que d'en implémenter un, mais voici comment vous pouvez utiliser chaque méthode pour affiner le type de variable de résultat :
declare type ValidationError = { err: unknown }; declare function isValidationError(val: unknown): val is ValidationError; declare const XMLValidator: { validate(message: unknown): true | ValidationError }; const message = 'test message'; const result = XMLValidator.validate(message) // You can check first if the result is `true` if (result === true) { // Handle success } else { // Then the `else` branch knows it much be a `ValidationError` console.error(result.err); } // Normally allowed, but not in this case. Error: // Type 'true | ValidationError' is not assignable to type 'object' if ('err' in result) { console.error(result.err) } if (isValidationError(result)) { console.error(result.err); }
Bien qu'il soit généralement préférable de les éviter, vous pouvez également utiliser TypeScript comme mot-clé pour les assertions de type.
La raison pour laquelle il est préférable d'éviter d'utiliser ces assertions de type est que vous dites à TypeScript de traiter un type comme un autre type. Par conséquent, en procédant ainsi, vous risquez de sacrifier la sécurité du type.
console.error((result as ValidationError).err);
Cependant, dans les situations où vous comprenez mieux la situation que le compilateur TypeScript, il s'agit d'un outil que vous pouvez utiliser pour lui fournir plus d'informations.
Personnellement, je trouve utile de toujours laisser un commentaire expliquant pourquoi une assertion de type a été utilisée, en mentionnant les hypothèses sur lesquelles repose sa sécurité.
De plus, dans ce cas, l'utilisation d'assertions de type pour vérifier les propriétés ne restreint pas le type de la variable de résultat, cette approche peut donc ne pas répondre exactement à vos besoins.