Es gibt verschiedene Situationen, in denen dieser Fehler auftritt. Im Fall des OP wurde ein Wert explizit als Zeichenfolge definiert . Ich muss also davon ausgehen, dass dies möglicherweise von einem Dropdown, einem Webdienst oder einer rohen JSON-Zeichenfolge stammt.
In diesem Fall ist eine einfache Besetzung <Fruit> fruitStringoder fruitString as Fruitdie einzige Lösung (siehe andere Antworten). Zum Zeitpunkt der Kompilierung könnten Sie dies niemals verbessern. [ Bearbeiten: Siehe meine andere Antwort über<const> ]!
Es ist jedoch sehr einfach, auf denselben Fehler zu stoßen, wenn Sie Konstanten in Ihrem Code verwenden, die niemals vom Typ string sein sollen . Meine Antwort konzentriert sich auf dieses zweite Szenario:
Zuallererst: Warum sind 'magische' String-Konstanten oft besser als eine Aufzählung?
- Ich mag die Art und Weise, wie eine String-Konstante im Vergleich zu einer Aufzählung aussieht - sie ist kompakt und "javascripty".
- Sinnvoller, wenn die von Ihnen verwendete Komponente bereits Zeichenfolgenkonstanten verwendet.
- Das Importieren eines 'Aufzählungstyps', nur um einen Aufzählungswert zu erhalten, kann an sich problematisch sein
- Was auch immer ich tue, ich möchte, dass es kompiliersicher ist. Wenn ich also einen gültigen Wert aus dem Union-Typ entferne oder falsch schreibe, MUSS es einen Kompilierungsfehler geben.
Zum Glück, wenn Sie definieren:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... Sie definieren tatsächlich eine Vereinigung von Typen, wobei 'missing'es sich tatsächlich um einen Typ handelt!
Ich stoße oft auf den Fehler 'nicht zuweisbar', wenn ich eine Zeichenfolge wie 'banana'in meinem Typoskript habe und der Compiler meint, ich hätte sie als Zeichenfolge gemeint, während ich wirklich wollte, dass sie vom Typ ist banana. Wie intelligent der Compiler sein kann, hängt von der Struktur Ihres Codes ab.
Hier ist ein Beispiel, wann ich diesen Fehler heute erhalten habe:
// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]
Sobald ich das herausfand, 'invalid'oder 'banana'entweder eine Art oder eine Zeichenfolge sein könnte mir klar , ich konnte es einfach assert einen String in dieser Art . Wirf es im Wesentlichen auf sich selbst und sage dem Compiler, nein, ich möchte nicht, dass dies eine Zeichenfolge ist !
// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]
Also, was ist falsch daran, nur zu FieldErrorType(oder Fruit) zu "gießen"?
// why not do this?
fieldErrors: [ { fieldName: 'number', error: <FieldErrorType> 'invalid' } ]
Es ist nicht sicher für die Kompilierung:
<FieldErrorType> 'invalidddd'; // COMPILER ALLOWS THIS - NOT GOOD!
<FieldErrorType> 'dog'; // COMPILER ALLOWS THIS - NOT GOOD!
'dog' as FieldErrorType; // COMPILER ALLOWS THIS - NOT GOOD!
Warum? Dies ist ein Typoskript, also <FieldErrorType>eine Behauptung, und Sie sagen dem Compiler, dass ein Hund ein FieldErrorType ist ! Und der Compiler wird es zulassen!
ABER wenn Sie Folgendes tun, konvertiert der Compiler die Zeichenfolge in einen Typ
<'invalid'> 'invalid'; // THIS IS OK - GOOD
<'banana'> 'banana'; // THIS IS OK - GOOD
<'invalid'> 'invalidddd'; // ERROR - GOOD
<'dog'> 'dog'; // ERROR - GOOD
Achten Sie auf solche dummen Tippfehler:
<'banana'> 'banan'; // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!
Eine andere Möglichkeit, das Problem zu lösen, besteht darin, das übergeordnete Objekt umzuwandeln:
Meine Definitionen waren wie folgt:
Exporttyp FieldName = 'Nummer' | 'expirationDate' | 'cvv'; Exporttyp FieldError = 'none' | 'fehlt' | 'ungültig'; Exporttyp FieldErrorType = {Feld: FieldName, Fehler: FieldError};
Nehmen wir an, wir erhalten einen Fehler (der nicht zuweisbare String-Fehler):
fieldErrors: [ { field: 'number', error: 'invalid' } ]
Wir können das ganze Objekt so "behaupten" FieldErrorType:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
Dann müssen wir das nicht tun <'invalid'> 'invalid'.
Aber was ist mit Tippfehlern? Nicht <FieldErrorType>nur behaupten , was auch immer auf der rechten Seite dieser Art zu sein. Nicht in diesem Fall - zum Glück des Compiler WILL beschweren , wenn Sie dies tun, weil sie klug genug , um zu wissen , es ist unmöglich:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
export type Fruit?