Folgendes habe ich inruit.ts
export type Fruit = "Orange" | "Apple" | "Banana"
Jetzt importiere ich obst.ts in eine andere Typoskriptdatei. Hier ist was ich habe
myString:string = "Banana";
myFruit:Fruit = myString;
Wenn ich es tue
myFruit = myString;
Ich erhalte eine Fehlermeldung:
Der Typ 'string' kann nicht dem Typ '"Orange" | zugewiesen werden "Apple" | "Banane"'
Wie kann ich einer Variablen vom benutzerdefinierten Typ Fruit eine Zeichenfolge zuweisen?
javascript
typescript
angular
user6123723
quelle
quelle
export type Fruit
?Antworten:
Du musst es besetzen :
Beachten Sie auch, dass Sie bei der Verwendung von Zeichenfolgenliteralen nur eines verwenden müssen
|
Bearbeiten
Wie in der anderen Antwort von @Simon_Weaver erwähnt, ist es jetzt möglich, dies zu behaupten
const
:quelle
const myFruit: Fruit = "Banana"
reichen.let myFruit:Fruit = "Apple" let something:string = myFruit as string
Es gibt mir einen Fehler: Die Konvertierung des Typs 'Fruit' in den Typ 'string' kann ein Fehler sein.as string
Teil. Ich habe Ihren Code auf dem Spielplatz ausprobiert und es gibt keine Fehler.const myString: string = 'Bananaaa';
mache, erhalte ich keine Kompilierungsfehler aufgrund des Castings ... gibt es keine Möglichkeit, dies zu tun, während ich die Zeichenfolge überprüfe?Typescript
3.4
führt die neue 'const'-Behauptung einSie können jetzt verhindern, dass Literaltypen (z. B.
'orange'
oder'red'
) erweitert werden, umstring
mit einer sogenanntenconst
Behauptung zu tippen .Sie werden in der Lage sein:
Und dann wird es sich nicht
string
mehr selbst zu einem - was die Wurzel des Problems in der Frage ist.quelle
let fruit = 'orange' as const;
wenn die No-Angle-Bracket-Type-Assertion-RegelWenn Sie dies tun:
... Sie erstellen einen Typ namens
Fruit
, der nur die Literale enthalten kann"Orange"
,"Apple"
und"Banana"
. Dieser Typ wird erweitertString
und kann daher zugewiesen werdenString
. WirdString
jedoch NICHT erweitert"Orange" | "Apple" | "Banana"
, kann es daher nicht zugewiesen werden.String
ist weniger spezifisch . Es kann eine beliebige Zeichenfolge sein .Wenn Sie dies tun:
...Es klappt. Warum? Da die tatsächliche Art des
myString
in diesem Beispiel ist"Banana"
. Ja,"Banana"
ist der Typ . Es ist erweitert,String
so dass es zuweisbar istString
. Zusätzlich ist eine Art erstreckt sich eine Art Union , wenn es sich jeder seiner Komponenten. In diesem Fall wird"Banana"
der Typ erweitert,"Orange" | "Apple" | "Banana"
weil er eine seiner Komponenten erweitert. Daher"Banana"
ist zuweisbar an"Orange" | "Apple" | "Banana"
oderFruit
.quelle
<'Banana'> 'Banana'
und das wird eine"Banana"
Zeichenfolge für"Banana"
den Typ "werfen" !!!<const> 'Banana'
was besser ist :-)Ich sehe, das ist ein bisschen alt, aber hier könnte es eine bessere Lösung geben.
Wenn Sie eine Zeichenfolge möchten, die Zeichenfolge jedoch nur mit bestimmten Werten übereinstimmen soll, können Sie Aufzählungen verwenden .
Beispielsweise:
Jetzt wissen Sie, dass myFruit immer die Zeichenfolge "Banana" ist (oder was auch immer Sie für einen anderen Wert wählen). Dies ist für viele Dinge nützlich, sei es, ähnliche Werte wie diese zu gruppieren oder benutzerfreundliche Werte maschinenfreundlichen Werten zuzuordnen, während gleichzeitig die vom Compiler zugelassenen Werte erzwungen und eingeschränkt werden.
quelle
let myFruit: Fruit = "Banana"
.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> fruitString
oderfruitString as Fruit
die 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?
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 istbanana
. 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:
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 !Also, was ist falsch daran, nur zu
FieldErrorType
(oderFruit
) zu "gießen"?Es ist nicht sicher für die Kompilierung:
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
Achten Sie auf solche dummen Tippfehler:
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):
Wir können das ganze Objekt so "behaupten"
FieldErrorType
: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:quelle
Alle oben genannten Antworten sind gültig. In einigen Fällen ist der String-Literal-Typ jedoch Teil eines anderen komplexen Typs. Betrachten Sie das folgende Beispiel:
Sie haben mehrere Lösungen, um dies zu beheben. Jede Lösung ist gültig und hat ihre eigenen Anwendungsfälle.
1) Die erste Lösung besteht darin, einen Typ für die Größe zu definieren und ihn aus foo.ts zu exportieren. Dies ist gut, wenn Sie mit dem Größenparameter selbst arbeiten müssen. Sie haben beispielsweise eine Funktion, die einen Parameter der Typgröße akzeptiert oder zurückgibt, und Sie möchten ihn eingeben.
2) Die zweite Option besteht darin, es einfach in den Typ ToolbarTheme umzuwandeln. In diesem Fall müssen Sie das interne ToolbarTheme nicht verfügbar machen, wenn Sie es nicht benötigen.
quelle
Wenn Sie
dropdownvalue[]
beispielsweise beim Verspotten von Daten ein Casting durchführen, erstellen Sie es als Array von Objekten mit Wert- und Anzeigeeigenschaften.Beispiel :
quelle
Ich hatte das gleiche Problem, habe die folgenden Änderungen vorgenommen und das Problem wurde behoben.
Öffnen Sie die Datei watchQueryOptions.d.ts
Ändern Sie den Abfragetyp any anstelle von DocumentNode . Gleich für Mutation
Vor:
Nach dem:
quelle