Il existe plusieurs situations qui vous donneront cette erreur particulière. Dans le cas de l'OP, il y avait une valeur définie explicitement comme une chaîne . Je dois donc supposer que cela provient peut-être d'une liste déroulante, d'un service Web ou d'une chaîne JSON brute.
Dans ce cas, un simple casting <Fruit> fruitString
ou fruitString as Fruit
est la seule solution (voir les autres réponses). Vous ne pourrez jamais améliorer cela au moment de la compilation. [ Edit: Voir mon autre réponse sur<const>
]!
Cependant, il est très facile de rencontrer cette même erreur lors de l'utilisation de constantes dans votre code qui ne sont jamais destinées à être de type chaîne . Ma réponse se concentre sur ce deuxième scénario:
Tout d'abord: pourquoi les constantes de chaîne «magiques» sont-elles souvent meilleures qu'une énumération?
- J'aime l'apparence d'une constante de chaîne par rapport à une énumération - c'est compact et 'javascripty'
- Cela a plus de sens si le composant que vous utilisez utilise déjà des constantes de chaîne.
- Devoir importer un `` type enum '' juste pour obtenir une valeur d'énumération peut être gênant en soi
- Quoi que je fasse, je veux qu'il soit compilé en toute sécurité, donc si j'ajoute supprimer une valeur valide du type d'union, ou la saisir mal, cela DOIT donner une erreur de compilation.
Heureusement lorsque vous définissez:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... vous définissez en fait une union de types où 'missing'
est en fait un type!
Je rencontre souvent l'erreur `` non assignable '' si j'ai une chaîne comme 'banana'
dans mon dactylographié et le compilateur pense que je l'ai signifiée comme une chaîne, alors que je voulais vraiment qu'elle soit de type banana
. L'intelligence du compilateur dépendra de la structure de votre code.
Voici un exemple de quand j'ai eu cette erreur aujourd'hui:
// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]
Dès que j'ai découvert cela 'invalid'
ou qu'il 'banana'
pouvait s'agir d'un type ou d'une chaîne, j'ai réalisé que je pouvais simplement affirmer une chaîne dans ce type . Essentiellement, lancez-le sur lui - même et dites au compilateur non, je ne veux pas que ce soit une chaîne !
// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]
Alors qu'est-ce qui ne va pas avec juste `` lancer '' vers FieldErrorType
(ou Fruit
)
// why not do this?
fieldErrors: [ { fieldName: 'number', error: <FieldErrorType> 'invalid' } ]
Le temps de compilation n'est pas sûr:
<FieldErrorType> 'invalidddd'; // COMPILER ALLOWS THIS - NOT GOOD!
<FieldErrorType> 'dog'; // COMPILER ALLOWS THIS - NOT GOOD!
'dog' as FieldErrorType; // COMPILER ALLOWS THIS - NOT GOOD!
Pourquoi? Il s'agit d' un texte dactylographié, donc d' <FieldErrorType>
une assertion et vous dites au compilateur qu'un chien est un FieldErrorType ! Et le compilateur le permettra!
MAIS si vous faites ce qui suit, le compilateur convertira la chaîne en un type
<'invalid'> 'invalid'; // THIS IS OK - GOOD
<'banana'> 'banana'; // THIS IS OK - GOOD
<'invalid'> 'invalidddd'; // ERROR - GOOD
<'dog'> 'dog'; // ERROR - GOOD
Attention aux fautes de frappe stupides comme celle-ci:
<'banana'> 'banan'; // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!
Une autre façon de résoudre le problème consiste à convertir l'objet parent:
Mes définitions étaient les suivantes:
type d'exportation FieldName = 'nombre' | 'expirationDate' | «cvv»; type d'exportation FieldError = 'none' | «manquant» | 'invalide'; type d'exportation FieldErrorType = {champ: FieldName, erreur: FieldError};
Disons que nous obtenons une erreur avec ceci (la chaîne d'erreur non attribuable):
fieldErrors: [ { field: 'number', error: 'invalid' } ]
Nous pouvons `` affirmer '' l'objet entier FieldErrorType
comme ceci:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
Alors on évite d'avoir à faire <'invalid'> 'invalid'
.
Mais qu'en est-il des fautes de frappe? Ne fonctionne pas <FieldErrorType>
simplement affirmer ce qui est sur le droit d'être de ce type. Pas dans ce cas - heureusement , le compilateur FERA porter plainte si vous faites cela, car il est assez intelligent pour savoir qu'il est impossible:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
export type Fruit
?