Aqui está o que eu tenho em fruit.ts
export type Fruit = "Orange" | "Apple" | "Banana"
Agora estou importando fruit.ts em outro arquivo datilografado. Aqui está o que eu tenho
myString:string = "Banana";
myFruit:Fruit = myString;
Quando eu faço
myFruit = myString;
Eu recebo um erro:
O tipo 'string' não é atribuível ao tipo '"Orange" | "Maçã" | "Banana"'
Como posso atribuir uma string a uma variável do tipo personalizado Fruit?
javascript
typescript
angular
user6123723
fonte
fonte
export type Fruit
?Respostas:
Você precisará transmiti-lo :
Observe também que, ao usar literais de string, você precisa usar apenas um
|
Editar
Conforme mencionado na outra resposta de @Simon_Weaver, agora é possível afirmar que
const
:fonte
const myFruit: Fruit = "Banana"
faria.let myFruit:Fruit = "Apple" let something:string = myFruit as string
Está me dando erro: A conversão do tipo 'Fruit' para o tipo 'string' pode ser um erro.as string
peça. Eu tentei seu código no playground e não há erros.const myString: string = 'Bananaaa';
, não recebo erros de compilação por causa do vazamento ... não há como fazer isso enquanto verifica a string?Texto datilografado
3.4
apresenta a nova asserção 'const'Agora você pode impedir que tipos literais (por exemplo,
'orange'
ou'red'
) sejam 'ampliados' para digitarstring
com a chamadaconst
asserção.Você será capaz de fazer:
E então não se tornará
string
mais - que é a raiz do problema na questão.fonte
let fruit = 'orange' as const;
quando seguinte regra de não-angle-suporte do tipo-afirmaçãoQuando você faz isso:
... você está criando um tipo chamado
Fruit
que pode conter apenas os literais"Orange"
,"Apple"
e"Banana"
. Esse tipo se estendeString
, portanto, pode ser atribuído aString
. No entanto,String
NÃO se estende"Orange" | "Apple" | "Banana"
, portanto, não pode ser atribuído a ele.String
é menos específico . Pode ser qualquer string .Quando você faz isso:
...funciona. Por quê? Uma vez que a real tipo de
myString
neste exemplo é"Banana"
. Sim,"Banana"
é o tipo . Ele se estendeString
para ser atribuível aString
. Além disso, um tipo estende um Tipo de União quando estende qualquer um de seus componentes. Nesse caso,"Banana"
o tipo se estende"Orange" | "Apple" | "Banana"
porque estende um de seus componentes. Portanto,"Banana"
é atribuível a"Orange" | "Apple" | "Banana"
ouFruit
.fonte
<'Banana'> 'Banana'
e isso 'moldará' uma"Banana"
string para"Banana"
o tipo !!!<const> 'Banana'
que é melhor :-)Vejo que isso é um pouco antigo, mas pode haver uma solução melhor aqui.
Quando você deseja uma sequência, mas deseja que ela corresponda apenas a determinados valores, pode usar enumerações .
Por exemplo:
Agora você saberá que não importa o quê, o myFruit sempre será a string "Banana" (ou qualquer outro valor enumerável que você escolher). Isso é útil para muitas coisas, seja agrupando valores semelhantes como esse ou mapeando valores amigáveis ao usuário para valores amigáveis à máquina, enquanto aplica e restringe os valores permitidos pelo compilador.
fonte
let myFruit: Fruit = "Banana"
.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
oufruitString 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?
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 tipobanana
. O quão inteligente o compilador é capaz dependerá da estrutura do seu código.Aqui está um exemplo de quando recebi esse erro hoje:
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 !Então, o que há de errado em apenas 'transmitir' para
FieldErrorType
(ouFruit
)Não é um tempo de compilação seguro:
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
Apenas atente para erros estúpidos como este:
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):
Podemos 'afirmar' todo o objeto
FieldErrorType
como este: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:fonte
Todas as respostas acima são válidas, no entanto, há alguns casos em que o Tipo literal de string faz parte de outro tipo complexo. Considere o seguinte exemplo:
Você tem várias soluções para corrigir isso. Cada solução é válida e possui seus próprios casos de uso.
1) A primeira solução é definir um tipo para o tamanho e exportá-lo do foo.ts. Isso é bom se você precisar trabalhar com o parâmetro size por conta própria. Por exemplo, você tem uma função que aceita ou retorna um parâmetro do tamanho do tipo e deseja digitá-lo.
2) A segunda opção é apenas convertê-la no tipo ToolbarTheme. Nesse caso, você não precisa expor o interno do ToolbarTheme, se não precisar.
fonte
Se você estiver convertendo para
dropdownvalue[]
quando estiver zombando de dados, por exemplo, componha-os como uma matriz de objetos com valor e propriedades de exibição.exemplo :
fonte
Eu estava enfrentando o mesmo problema, fiz as alterações abaixo e o problema foi resolvido.
Abrir arquivo watchQueryOptions.d.ts
Altere o tipo de consulta any em vez de DocumentNode , Same para mutação
Antes:
Depois de:
fonte