«Type 'string' is not assignable to type» — o que é e por que você está aqui?
\n\nSe você já escreveu em TypeScript, certamente já se deparou com o sublinhado vermelho no editor de código e a mensagem:
\n\nType 'string' is not assignable to type 'SomeType'.\n\nEste erro é um verdadeiro «alô» da tipagem forte. Ele assusta iniciantes, mas na verdade é o melhor amigo do desenvolvedor. Neste artigo, vamos entender por que ocorre o erro Type 'string' is not assignable to type, como corrigi-lo e quais abordagens existem para trabalhar com literais de string, union types e genéricos. O artigo foi escrito para o site educacional pythonlib.ru, mas os exemplos são totalmente em TypeScript.
\n\n1. Raiz do problema: por que o TypeScript reclama de strings?
\n\nTypeScript é uma extensão do JavaScript que adiciona tipagem estática. Quando você escreve:
\n\nlet role: 'admin' | 'user' = 'admin';\nrole = 'moderator'; // Erro: Type '"moderator"' is not assignable to type '"admin" | "user"'\n\n\nO TypeScript entende que a variável role pode aceitar apenas dois valores: 'admin' ou 'user'. Quando você tenta atribuir 'moderator', o compilador gera um erro. Mas por que ele escreve «Type 'string' is not assignable to type»?
A questão é que o literal de string 'moderator' tem o tipo string, enquanto o tipo esperado é 'admin' | 'user'. O TypeScript compara tipos, não valores. Ele vê: «Você está me dando uma string comum, mas eu espero strings específicas». Daí a mensagem.
1.1. Exemplo simples para entender
\n\nVamos considerar um caso básico:
\n\ntype Status = 'active' | 'inactive';\n\nfunction updateStatus(status: Status) {\n console.log(status);\n}\n\nconst myStatus = 'active';\nupdateStatus(myStatus); // OK\n\nconst anotherStatus = 'pending';\nupdateStatus(anotherStatus); // Erro: Type 'string' is not assignable to type 'Status'\n\n\nNo último caso, a variável anotherStatus é inferida como string, e não como 'pending'. O TypeScript não sabe que 'pending' é um literal. Ele vê apenas o tipo string. Isso pode ser corrigido especificando explicitamente o tipo:
const anotherStatus: 'pending' = 'pending'; // Agora funciona\n\n\n2. Comparação de abordagens: como contornar ou corrigir o erro
\n\nExistem várias maneiras de lidar com o erro Type 'string' is not assignable to type. Vamos compará-las em termos de simplicidade, segurança e desempenho.
\n\n2.1. Abordagem 1: as const — congelamento do literal
\n\nA maneira mais elegante é usar as const. Ele «congela» o valor como um literal:
const myStatus = 'active' as const;\nupdateStatus(myStatus); // OK\n\n\nVantagens: simples, legível, seguro.
\nDesvantagens: funciona apenas com const, não com let.
2.2. Abordagem 2: Type Assertion (as) — conversão explícita
\n\nVocê pode dizer ao TypeScript: «Eu sei o que estou fazendo»:
\n\nconst someString: string = 'active';\nupdateStatus(someString as Status); // OK\n\n\nVantagens: solução rápida.
\nDesvantagens: você desativa a verificação de tipos. Se passar um valor inválido, o erro só aparecerá em tempo de execução.
2.3. Abordagem 3: Type Guard (guardião de tipo)
\n\nVamos escrever uma função que verifica se a string é um status válido:
\n\nfunction isStatus(value: string): value is Status {\n return value === 'active' || value === 'inactive';\n}\n\nfunction safeUpdate(value: string) {\n if (isStatus(value)) {\n updateStatus(value); // TypeScript sabe que value é Status\n } else {\n throw new Error('Status inválido');\n }\n}\n