recherche

Maison  >  Questions et réponses  >  le corps du texte

JavaScript a des wrappers d'objets qui me permettent de vérifier si la "propriété" d'un type primitif existe, alors comment puis-je faire fonctionner TypeScript comme ceci également ?

<p>La valeur de retour de XMLValidator.validate est soit true, soit une ValidationError (ce qui n'est pas tout à fait exact, voir ma mise à jour), et ValidationError a un attribut err. </p> <pre class="brush:php;toolbar:false;">validate(xmlData: string, options?: validationOptionsOptional): true | ValidationError</pre> <p>Étant donné que JavaScript utilise des wrappers d'objet pour représenter les valeurs primitives booléennes, je peux savoir si la validation a réussi en vérifiant si l'attribut err existe. </p> <pre class="brush:php;toolbar:false;">const résultat = XMLValidator.validate(message) if (result.err) { // Comment puis-je le faire fonctionner dans ts ? console.log(`XML invalide) } autre { console.log(`XML) }</pré> <p>Mais TypeScript ne me permet pas de faire cela, il signalera une erreur : L'attribut 'err' n'existe pas sur le type "vrai". </p><p>Je n'aime pas l'idée de vérifier d'abord le type de retour car je le trouve verbeux et il n'y a vraiment pas de définition du type de valeur de retour (voir ma mise à jour). Comment dois-je écrire du code TypeScript de la manière la plus concise possible ? </p><p>--- Mise à jour ---</p><p>J'ai en outre vérifié le code de validator.js. </p><p><br /></p> <pre class="brush:php;toolbar:false;">const isValid = validateAttributeString(attrStr, options); si (isValid !== vrai) { return getErrorObject(...); } ... fonction getErrorObject (code, message, numéro de ligne) { retour { euh : { code:code, msg : message, ligne : numéro_ligne.ligne || col: lineNumber.col, }, } ; }</pré> <p>Il semble donc que je ne puisse utiliser que if (typeof result == "boolean") ici, mais j'espère qu'il existe une solution "universelle" à ma question. </p>
P粉797855790P粉797855790495 Il y a quelques jours493

répondre à tous(1)je répondrai

  • P粉957723124

    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);
    }
    

    Aire de jeux TypeScript


    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.

    répondre
    0
  • Annulerrépondre