Nullable em TypeScript: como declarar um tipo que pode ser null?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

TypeScript e sua pergunta eterna: como tornar um tipo nullable?

\n\n

Olá, colega! Se você já escreveu em TypeScript, certamente já se deparou com uma situação em que uma função pode retornar um valor, ou pode não retornar. Ou uma variável não é inicializada imediatamente. E surge a pergunta sacramental: como declarar um tipo que pode ser null ou undefined?

\n\n

Esta pergunta é uma das mais populares no Stack Overflow (dezenas de milhares de visualizações!), e não é à toa. TypeScript é rigoroso, mas justo. Ele não nos permite simplesmente atribuir null a uma variável do tipo string. E isso é ótimo, porque nos salva de uma tonelada de bugs. Mas como fazer quando nullable é parte da lógica de negócios? Vamos descobrir.

\n\n

Neste artigo, não vamos apenas dar uma resposta seca. Vamos desde o básico até técnicas avançadas, analisar erros comuns e aprender a escrever código que seja seguro e elegante. Vamos nessa!

\n\n

Fundamentos: Union Types e Null

\n\n

A maneira mais simples e direta de tornar um tipo nullable é usar union type (união de tipos). Se uma variável pode ser uma string ou null, escrevemos assim:

\n\n
let userName: string | null = null;\nuserName = "Alice"; // Ok\nuserName = null;    // Também ok\n
\n\n

O mesmo funciona com undefined. Em TypeScript, null e undefined são tipos diferentes (a menos que a flag --strictNullChecks esteja desabilitada, mas falaremos disso mais adiante).

\n\n
let age: number | undefined;\nage = 25;\nage = undefined; // Funciona\n
\n\n

Importante: se você usar | null ou | undefined, o TypeScript forçará você a verificar o valor antes de usá-lo. Tentar chamar um método em um objeto potencialmente null resultará em um erro de compilação. Essa é a tal "segurança" pela qual amamos o TS.

\n\n

Exemplo da vida real: busca de usuário

\n\n
interface User {\n  id: number;\n  name: string;\n}\n\nfunction findUser(id: number): User | null {\n  // ...lógica de busca\n  if (id === 1) {\n    return { id: 1, name: "Ivan" };\n  }\n  return null;\n}\n\nconst user = findUser(2);\n// user.name; // Erro! 'user' pode ser null\nif (user) {\n  console.log(user.name); // Agora é seguro\n}\n
\n\n

Viu? O compilador te avisa: "Ei, verifique, senão vai quebrar!". Isso economiza horas de depuração.

\n\n

Parâmetros e propriedades opcionais (Optional Chaining)

\n\n

Frequentemente, nullable não são apenas variáveis, mas também campos de objetos ou argumentos de funções. Para isso, o TypeScript tem uma sintaxe especial — o optional modifier (ponto de interrogação ?).

\n\n

Parâmetros opcionais de função

\n\n
function greet(name?: string) {\n  if (name) {\n    return `Olá, ${name}!`;\n  }\n  return "Olá, estranho!";\n}\n\nconsole.log(greet("Pedro")); // Olá, Pedro!\nconsole.log(greet());       // Olá, estranho!\n
\n\n

O tipo do parâmetro name se torna automaticamente string | undefined. Observe: se o parâmetro é opcional, você pode não passá-lo, e o TS não reclamará.

\n\n

Propriedades opcionais de interfaces

\n\n
interface Config {\n  url: string;\n  port?: number; // pode ser number ou undefined\n}\n\nconst config1: Config = { url: "http://localhost" }; // port está ausente\nconst config2: Config = { url: "http://localhost", port: 3000 };\n
\n\n

Ao acessar config1.port, o TypeScript dirá que é number | undefined. E isso é correto — não sabemos se a porta foi definida.

\n\n

Encadeamento opcional (Optional Chaining) — seu melhor amigo

\n\n

Com o surgimento do ES2020 e TypeScript 3.7, temos uma maneira elegante de acessar com segurança propriedades aninhadas que podem ser null ou undefined. Isso é chamado de optional chaining

Blogs

Book Recommendations