Hay varias situaciones que le darán este error particular. En el caso del OP, había un valor definido explícitamente como una cadena . Entonces, debo suponer que tal vez esto vino de un menú desplegable, o servicio web o cadena JSON sin procesar.
En ese caso, un elenco simple <Fruit> fruitStringo fruitString as Fruites la única solución (ver otras respuestas). Nunca podría mejorar esto en tiempo de compilación. [ Editar: ¡Mira mi otra respuesta sobre<const> ]!
Sin embargo, es muy fácil encontrarse con este mismo error cuando se usan constantes en su código que nunca pretenden ser de tipo cadena . Mi respuesta se centra en ese segundo escenario:
En primer lugar: ¿por qué las constantes de cadena 'mágicas' a menudo son mejores que una enumeración?
- Me gusta cómo se ve una cadena constante frente a una enumeración: es compacta y 'javascripty'
- Tiene más sentido si el componente que está utilizando ya usa constantes de cadena.
- Tener que importar un 'tipo de enumeración' solo para obtener un valor de enumeración puede ser problemático en sí mismo
- Independientemente de lo que haga, quiero que sea seguro para la compilación, por lo que si agrego eliminar un valor válido del tipo de unión o escribirlo incorrectamente, DEBE dar un error de compilación.
Afortunadamente cuando define:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... en realidad estás definiendo una unión de tipos donde 'missing'realmente es un tipo!
A menudo me encuentro con el error 'no asignable' si tengo una cadena como 'banana'en mi mecanografiado y el compilador cree que lo dije como una cadena, mientras que realmente quería que fuera de tipo banana. Lo inteligente que pueda ser el compilador dependerá de la estructura de su código.
Aquí hay un ejemplo de cuándo recibí este error hoy:
// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]
Tan pronto como descubrí eso 'invalid'o 'banana'podría ser un tipo o una cadena, me di cuenta de que podía afirmar una cadena en ese tipo . Esencialmente, házlo en sí mismo y dile al compilador que no, ¡no quiero que sea una cadena !
// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]
¿Cuál es tan malo con sólo 'fundición' a FieldErrorType(o Fruit)
// why not do this?
fieldErrors: [ { fieldName: 'number', error: <FieldErrorType> 'invalid' } ]
No es tiempo de compilación seguro:
<FieldErrorType> 'invalidddd'; // COMPILER ALLOWS THIS - NOT GOOD!
<FieldErrorType> 'dog'; // COMPILER ALLOWS THIS - NOT GOOD!
'dog' as FieldErrorType; // COMPILER ALLOWS THIS - NOT GOOD!
¿Por qué? Esto es mecanografiado, así que <FieldErrorType>es una afirmación y le está diciendo al compilador que un perro es un FieldErrorType . ¡Y el compilador lo permitirá!
PERO si haces lo siguiente, el compilador convertirá la cadena a un tipo
<'invalid'> 'invalid'; // THIS IS OK - GOOD
<'banana'> 'banana'; // THIS IS OK - GOOD
<'invalid'> 'invalidddd'; // ERROR - GOOD
<'dog'> 'dog'; // ERROR - GOOD
Solo ten cuidado con errores estúpidos como este:
<'banana'> 'banan'; // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!
Otra forma de resolver el problema es lanzar el objeto padre:
Mis definiciones fueron las siguientes:
tipo de exportación FieldName = 'número' | 'expirationDate' | 'cvv'; tipo de exportación FieldError = 'none' | 'desaparecido' | 'inválido'; tipo de exportación FieldErrorType = {field: FieldName, error: FieldError};
Digamos que tenemos un error con esto (el error de cadena no asignable):
fieldErrors: [ { field: 'number', error: 'invalid' } ]
Podemos 'afirmar' todo el objeto de FieldErrorTypeesta manera:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
Entonces evitamos tener que hacer <'invalid'> 'invalid'.
¿Pero qué hay de los errores tipográficos? No <FieldErrorType>solo afirma lo que está a la derecha de ser de ese tipo. No en este caso - por suerte el compilador SE quejarse si usted hace esto, porque es lo suficientemente inteligente para saber que es imposible:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
export type Fruit?