Publicado em

- 3 minutos de leitura

Angular: O Problema com o NULL em Signal Forms

img of 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)
}
Imagem com o texto: Curso Formulários com Angular e com a logo do Angular e um formulário. Logo abaixo existe um botão com o texto "Eu quero!"

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

Author's photo
Henrique Custódia Arquiteto Frontend, entusiasta Angular, cat lover, criador de conteúdo e fundador da Code Dimension!