No Angular não é bom usar o Zod para validação de formulário justamente porque ali já temos meios nativos de se fazer isso.

Mas isso não quer dizer que o Zod seja descartável em um projeto Angular.

O Zod brilha em lugares como, por exemplo, respostas de APIs. Imagina que sua app espera receber um JSON assim:

{ "id": 1, "name": "Fulano da Silva", "active": 2 }

E vc constrói toda sua lógica esperando receber um ID numérico e uma propriedade active com os valores 2 para "ativo" e 1 para "inativo".

type User = { id: number; name: string; active: 1 | 2 };

@Injectable({ providedIn: "root" })
export class UserService {
  getAll(): Observable<User[]> {
    // Faz de conta que tá vindo do HttpClient 😉
    return of([
      { id: 1, name: "João", active: 2 },
      { id: 2, name: "Maria", active: 1 },
    ]);
  }
}

Num belo dia, os devs da API decidem que agora a propriedade active deve ser um booleano e que o ID seria um UUID. Pronto! Sua lógica pode falhar.

Em algum momento vc vai perceber que a falha não vem da sua app, mas da resposta da API, mas com o Zod vc descobriria logo de cara onde o problema vem.

const userSchema = z.object({
  id: z.number(),
  name: z.string(),
  active: z.union([z.literal(1), z.literal(2)]),
});

type User = z.infer<typeof userSchema>;

// ...

getAll(): Observable<User[]> {
  // Faz de conta que tá vindo do HttpClient 😉
  return of([
    {
      id: "c2fa20d9-e248-4e96-b003-904fc13a3e9f",
      name: "João",
      active: true,
    },
    {
      id: "3ae4e6bf-9622-400e-bda7-5ce110519382",
      name: "Maria",
      active: false,
    },
  ] as any).pipe(map((e) => userSchema.array().parse(e)));
}

Interessante esse uso, nunca pensei em fazer validação de dados vindo da API com Zod. Eu sempre fiz na mão, porque é um procedimento simples. Mas se a gente escalar o payload pra objetos mais complexos, o Zod encaixa certinho.