Publicado em
- 3 minutos de leitura
Angular: O Problema com o NULL em Signal Forms
Com a chegada do Angular 21.2, Signal Forms consolidaram uma nova forma de lidar com formulários de maneira reativa e performática.
No entanto, uma mudança importante na tipagem rigorosa trouxe um desafio para quem estava acostumado com o antigo Reactive Forms: o uso do valor null em campos que esperam dados específicos.
Neste artigo, vamos entender por que o null pode causar erros de compilação, como evitar o uso de “hacks” e qual é a arquitetura recomendada para manter seu código limpo e seguro usando Signals.
Se preferir, assista o vídeo diretamente no YouTube:
O Conflito entre NULL e Inputs Nativos
Ao utilizar o novo Signal Forms, você notará que tentar vincular um Signal que aceita null a um elemento <input> ou <textarea> comum gera um erro de tipagem.
Isso ocorre porque os elementos nativos do HTML trabalham essencialmente com strings, e o sistema de tipos do Angular entende que null não é um valor compatível com o que esses elementos esperam receber.
O exemplo abaixo mostra exatamente onde o compilador do TypeScript interrompe o processo por incompatibilidade de tipos:
<input
type="text"
class="input w-full"
[formField]="form.name"
/* Erro: 'string | null' não é atribuível ao tipo 'string' */
/>
Contornando o problema com $any(…)
Uma solução comum, porém desencorajada, é utilizar a função $any() no template para forçar a aceitação do valor. Isso faz com que o erro de tipagem desapareça, permitindo a compilação do projeto.
O grande problema dessa abordagem é que você desativa a segurança de tipos do Angular.
Ao usar $any(), você perde o mapeamento automático do Signal, o que pode esconder bugs silenciosos que só aparecerão em tempo de execução, anulando um dos maiores benefícios de Signal Forms.
<input
type="text"
class="input w-full"
[formField]="$any(form.name)"
/* Não recomendado: quebra a integridade da tipagem do formulário */
/>
A Estratégia Recomendada: Valores Simbólicos
A recomendação oficial do time do Angular é evitar o null para campos que possuem valores padrão claros, como textos ou números.
Em vez de usar null para representar um campo vazio, devemos usar valores que o HTML entenda nativamente: uma string vazia ('') para textos ou 0/NaN para campos numéricos.
O null deve ser reservado exclusivamente para casos onde a ausência de valor tem um significado semântico real ou para Custom Controls específicos. Veja como estruturar seu modelo de forma correta:
interface UserModel {
name: string
email: string
value: number
birthdate: Date | null // Null permitido aqui para representar data não selecionada
}
export class UserComponent {
// Inicialização seguindo a recomendação oficial
protected model = signal<UserModel>({
name: '',
email: '',
value: 0,
birthdate: null
})
protected form = form(this.model)
}
Flexibilidade com Custom Controls
Para componentes personalizados que você mesmo cria, a história é diferente.
Como você controla a lógica interna do componente, ele pode ser projetado para aceitar e tratar o null sem problemas.
Signal Forms permite que esses Custom Controls usem o null para sinalizar estados como “não preenchido” ou “resetado”.
Abaixo, um exemplo de um componente customizado que recebe um Signal que pode ser nulo e utiliza um computed() para processar a informação de forma segura:
@Component({
selector: 'app-custom-control',
template: `
<div>
<p>Idade calculada: {{ currentAge() }}</p>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CustomControl implements FormValueControl<Date | null> {
readonly value = model.required<Date | null>()
// O Signal computed lida com a verificação de nulidade
protected currentAge = computed(() => {
const date = this.value()
// Verifica se é um valor "falsy"
if (!date) {
return 0
}
const birthDate = new Date(date)
const diff = Date.now() - birthDate.getTime()
const ageDate = new Date(diff)
return Math.abs(ageDate.getUTCFullYear() - 1970)
})
}
Conclusão
Dominar o comportamento de null em Signal Forms é um passo essencial para escrever aplicações Angular modernas e livres de erros de tipagem.
Ao optar por valores padrão como strings vazias em campos nativos, você mantém a integridade do seu código e aproveita ao máximo o poder de detecção de erros do compilador.
Embora o uso de nulos tenha sido comum no passado, a nova era baseada em Signals nos convida a ser mais explícitos sobre o que cada campo representa.
Componentes customizados continuam oferecendo a flexibilidade necessária para casos complexos, garantindo que seu formulário seja robusto e fácil de manter a longo prazo.
Assine nossa Newsletter
Receba novos posts como esse na sua caixa de e-mail!
Sobre o autor