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> fruitString
o fruitString as Fruit
es 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 FieldErrorType
esta 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
?