Existem várias situações que fornecerão esse erro específico. No caso do OP, havia um valor definido explicitamente como uma sequência . Portanto, devo assumir que talvez isso tenha sido causado por uma lista suspensa, serviço da Web ou string JSON não processada.
Nesse caso, um elenco simples <Fruit> fruitString
ou fruitString as Fruit
é a única solução (veja outras respostas). Você nunca seria capaz de melhorar isso em tempo de compilação. [ Editar: Veja minha outra resposta sobre<const>
]!
No entanto, é muito fácil encontrar esse mesmo erro ao usar constantes no seu código que nunca pretendem ser do tipo string . Minha resposta se concentra nesse segundo cenário:
Primeiro de tudo: Por que as constantes de seqüência de caracteres 'mágicas' geralmente são melhores que um enum?
- Eu gosto da aparência de uma constante de string versus uma enumeração - é compacta e 'javascripty'
- Faz mais sentido se o componente que você está usando já usa constantes de string.
- Ter que importar um 'tipo de enumeração' apenas para obter um valor de enumeração pode ser problemático por si só
- O que quer que eu faça, quero que ele seja compilado com segurança. Se eu adicionar remover um valor válido do tipo de união ou digitar errado, DEVE dar um erro de compilação.
Felizmente, quando você define:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... na verdade você está definindo uma união de tipos onde 'missing'
é realmente um tipo!
Geralmente, encontro o erro 'não atribuível' se eu tiver uma string como 'banana'
no meu texto datilografado e o compilador achar que eu quis dizer isso como uma string, enquanto eu realmente queria que fosse do tipo banana
. O quão inteligente o compilador é capaz dependerá da estrutura do seu código.
Aqui está um exemplo de quando recebi esse erro hoje:
// this gives me the error 'string is not assignable to type FieldErrorType'
fieldErrors: [ { fieldName: 'number', error: 'invalid' } ]
Assim que descobri isso 'invalid'
ou 'banana'
poderia ser um tipo ou uma string, percebi que poderia apenas afirmar uma string nesse tipo . Elenco essencial para si mesmo , e diga ao compilador não, não quero que isso seja uma string !
// so this gives no error, and I don't need to import the union type too
fieldErrors: [ { fieldName: 'number', error: <'invalid'> 'invalid' } ]
Então, o que há de errado em apenas 'transmitir' para FieldErrorType
(ou Fruit
)
// why not do this?
fieldErrors: [ { fieldName: 'number', error: <FieldErrorType> 'invalid' } ]
Não é um tempo de compilação 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ê? Isso é datilografado, então <FieldErrorType>
é uma afirmação e você está dizendo ao compilador que um cachorro é um FieldErrorType ! E o compilador permitirá!
MAS se você fizer o seguinte, o compilador converterá a string em um tipo
<'invalid'> 'invalid'; // THIS IS OK - GOOD
<'banana'> 'banana'; // THIS IS OK - GOOD
<'invalid'> 'invalidddd'; // ERROR - GOOD
<'dog'> 'dog'; // ERROR - GOOD
Apenas atente para erros estúpidos como este:
<'banana'> 'banan'; // PROBABLY WILL BECOME RUNTIME ERROR - YOUR OWN FAULT!
Outra maneira de resolver o problema é lançando o objeto pai:
Minhas definições foram as seguintes:
tipo de exportação FieldName = 'number' | 'expirationDate' | 'cvv'; tipo de exportação FieldError = 'none' | 'ausente' | 'inválido'; tipo de exportação FieldErrorType = {field: FieldName, erro: FieldError};
Digamos que obtivemos um erro com isso (a string não pode ser atribuída):
fieldErrors: [ { field: 'number', error: 'invalid' } ]
Podemos 'afirmar' todo o objeto FieldErrorType
como este:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'invalid' } ]
Então evitamos ter que fazer <'invalid'> 'invalid'
.
Mas e os erros de digitação? Não afirma<FieldErrorType>
apenas o que está à direita para ser desse tipo. Não neste caso - felizmente o compilador VAI reclamar se você fizer isso, porque é inteligente o suficiente para saber que é impossível:
fieldErrors: [ <FieldErrorType> { field: 'number', error: 'dog' } ]
export type Fruit
?