Desafio TypeScript
Narrowing com união discriminada e análise de fluxo
Enunciado
Defina uma união discriminada Resultado que representa o resultado de uma operação: { sucesso: true, valor: number } ou { sucesso: false, erro: string }. Implemente uma função processar que recebe um Resultado e retorna uma string descritiva. Use narrowing por igualdade na propriedade sucesso. Além disso, trate o caso em que a entrada pode ser null ou undefined usando narrowing com typeof ou verificação de nulidade.
Requisitos
- Definir o tipo
Resultadocomo união discriminada. - Usar
if (resultado.sucesso)para estreitar. - Tratar
null | undefinedantes de acessar propriedades. - Retornar string em todos os caminhos.
Código inicial
type Resultado =
| { sucesso: true; valor: number }
| { sucesso: false; erro: string };
function processar(resultado: Resultado | null | undefined): string {
// Seu código aqui
}
console.log(processar({ sucesso: true, valor: 42 }));
console.log(processar({ sucesso: false, erro: 'Falha' }));
console.log(processar(null));
Saída esperada
Sucesso: 42
Erro: Falha
Sem resultado
Ver dica
Primeiro verifique se resultado é null ou undefined. Depois use resultado.sucesso para distinguir os casos.
Mostrar solução
type Resultado =
| { sucesso: true; valor: number }
| { sucesso: false; erro: string };
function processar(resultado: Resultado | null | undefined): string {
if (resultado == null) {
return 'Sem resultado'; // trata null e undefined
}
if (resultado.sucesso) {
return `Sucesso: ${resultado.valor}`; // resultado é { sucesso: true }
} else {
return `Erro: ${resultado.erro}`; // resultado é { sucesso: false }
}
}
console.log(processar({ sucesso: true, valor: 42 }));
console.log(processar({ sucesso: false, erro: 'Falha' }));
console.log(processar(null));
Passo a passo
- Definimos o tipo
Resultadocomo uma união discriminada pela propriedadesucesso. - A função
processaraceitaResultado | null | undefined. - Usamos
if (resultado == null)para capturar tantonullquantoundefined(o==solto faz essa verificação combinada). - Dentro do
if, retornamos a string padrão. - Fora do
if, o TypeScript sabe queresultadoéResultado. - Verificamos
resultado.sucesso: setrue, acessamosvalor; sefalse, acessamoserro.
Por que funciona
A análise de fluxo do TypeScript rastreia o tipo de resultado através dos blocos condicionais. A verificação == null estreita a união removendo null e undefined. Em seguida, a propriedade discriminante sucesso (um literal booleano) permite que o TypeScript saiba exatamente qual variante da união está presente em cada ramo.
Erros comuns
- Usar
if (resultado)para checar null: isso também rejeita{ sucesso: false }porque objetos são truthy, mas pode confundir. Prefira== null. - Acessar
resultado.valorsem verificarsucesso:
return resultado.valor; // Erro: Property 'valor' does not exist on type '{ sucesso: false; erro: string; }' - Esquecer de tratar
undefinede receber erro de tipo.
Outra forma de resolver
Usar switch na propriedade sucesso:
switch (resultado?.sucesso) {
case true: return `Sucesso: ${resultado.valor}`;
case false: return `Erro: ${resultado.erro}`;
default: return 'Sem resultado';
}
Útil quando há mais variantes.
Saída esperada
Sucesso: 42
Erro: Falha
Sem resultado