suchen

Heim  >  Fragen und Antworten  >  Hauptteil

JavaScript verfügt über Objekt-Wrapper, mit denen ich überprüfen kann, ob die „Eigenschaft“ eines primitiven Typs vorhanden ist. Wie kann ich also dafür sorgen, dass TypeScript auch so funktioniert?

<p>Der Rückgabewert von XMLValidator.validate ist entweder true oder ein ValidationError (was nicht ganz korrekt ist, siehe mein Update), und ValidationError hat ein Fehlerattribut. </p> <pre class="brush:php;toolbar:false;">validate(xmlData: string, options?: validationOptionsOptional): true |. <p>Da JavaScript Objekt-Wrapper verwendet, um boolesche Grundwerte darzustellen, kann ich feststellen, ob die Validierung erfolgreich war, indem ich überprüfe, ob das err-Attribut vorhanden ist. </p> <pre class="brush:php;toolbar:false;">const result = XMLValidator.validate(message) if (result.err) { // Wie sorge ich dafür, dass es in ts funktioniert? console.log(`ungültiges XML) } anders { console.log(`XML) }</pre> <p>Aber TypeScript erlaubt mir dies nicht, es wird ein Fehler gemeldet: Das Attribut „err“ existiert nicht für den Typ „true“. </p><p>Mir gefällt die Idee nicht, zuerst den Rückgabetyp zu überprüfen, weil ich ihn ausführlich finde und es wirklich keine Definition des Rückgabewerttyps gibt (siehe mein Update). Wie soll ich TypeScript-Code möglichst prägnant schreiben? </p><p>--- Update ---</p><p>Ich habe den Code von validator.js weiter überprüft. </p><p><br /></p> <pre class="brush:php;toolbar:false;">const isValid = validateAttributeString(attrStr, options); if (isValid !== true) { return getErrorObject(...); } ... Funktion getErrorObject(code, message, lineNumber) { zurückkehren { irren: { Code: Code, msg: Nachricht, Zeile: lineNumber.line ||. lineNumber, col: lineNumber.col, }, }; }</pre> <p>Es sieht also so aus, als ob ich hier nur if (typeof result == "boolean") verwenden kann, aber ich hoffe, dass es eine "universelle" Lösung für meine Frage gibt. </p>
P粉797855790P粉797855790547 Tage vor514

Antworte allen(1)Ich werde antworten

  • P粉957723124

    P粉9577231242023-07-29 09:49:07

    你说得对,TypeScript不允许你访问它不知道在变量类型上可能存在的属性。如果该类型是一个联合类型,那么在TypeScript允许你访问之前,该属性必须存在于该联合类型的所有成员上。

    但是可以通过各种方法来缩小变量的类型。例如,你可以首先检查值是否为true,如果不是,则TypeScript将将联合类型缩小为仅为ValidationError。

    通常,另一种选择是使用in运算符,但在这种情况下,联合类型不仅包含对象类型,所以TypeScript不允许使用它。

    你还可以定义一个自定义类型保护(或使用库中提供的类型保护,如果存在的话),但对于这种简单的情况来说,这似乎可能是你想要的工作量有点太大。

    正如我提供的TypeScript文档详细说明的那样,还有其他缩小类型的方法。像你提到的,检查typeof运算符的结果也是其中的一种方法。

    这个例子只是声明了一个类型保护存在,而不是实现一个,但是下面是你可以使用每种方法来缩小result变量类型的方式:

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

    TypeScript Playground


    虽然它们通常最好避免使用,但你还可以使用TypeScript的as关键字来进行类型断言。

    之所以最好避免使用这些类型断言,是因为你告诉TypeScript将一个类型视为其他类型。因此,通过这样做,你可能会牺牲类型安全性。


    console.error((result as ValidationError).err);
    

    然而,在你对情况的理解比TypeScript编译器更好的情况下,这是你可以使用的工具,以向它提供更多信息。

    就个人而言,我发现这是一种有帮助的方法,总是留下注释解释为什么使用了类型断言,提及其安全性基于的任何假设。

    此外,在这种情况下,使用类型断言来检查属性不会缩小result变量的类型,所以这种方法可能不完全符合你的需求。

    Antwort
    0
  • StornierenAntwort