Pular para o conteúdo
ValidadorCNPJ Gerar CNPJ

TypeScript · código pronto

Validar CNPJ alfanumérico em TypeScript

Validador de CNPJ alfanumérico em TypeScript com tipos, guard de tipo e zero dependências.

Testar um CNPJ agora Gerar massa de teste

Versão tipada do algoritmo, com um type guard e um tipo Cnpj de marca (branded type) para você não confundir uma string qualquer com um CNPJ já validado.

O algoritmo é sempre o mesmo: cada caractere vale o seu código ASCII menos 48 (0=0 … 9=9, A=17 … Z=42), os pesos vão de 2 a 9 da direita para a esquerda, soma-se tudo, divide-se por 11 e o dígito é 0 quando o resto é menor que 2, ou 11 menos o resto. Ver a conta detalhada.

Código completo

validação de CNPJ alfanumérico em TypeScript
export type Cnpj = string & { readonly __marca: 'cnpj' };

const NAO_ALFANUMERICO = /[^0-9A-Z]/g;
const FORMATO = /^[0-9A-Z]{12}\d{2}$/;
const REPETIDO = /^(.)\1{13}$/;

export function limparCnpj(valor: string): string {
  return (valor ?? '').toUpperCase().replace(NAO_ALFANUMERICO, '');
}

function digito(sequencia: string): number {
  let soma = 0;
  for (let i = 0; i < sequencia.length; i += 1) {
    const valor = sequencia.charCodeAt(i) - 48;
    const peso = ((sequencia.length - 1 - i) % 8) + 2;
    soma += valor * peso;
  }
  const resto = soma % 11;
  return resto < 2 ? 0 : 11 - resto;
}

export function calcularDv(base: string): string {
  const primeiro = digito(base);
  const segundo = digito(`${base}${primeiro}`);
  return `${primeiro}${segundo}`;
}

/** Type guard: estreita o tipo para Cnpj quando a validação passa. */
export function ehCnpj(valor: string): valor is Cnpj {
  const cnpj = limparCnpj(valor);
  if (!FORMATO.test(cnpj) || REPETIDO.test(cnpj)) return false;
  return calcularDv(cnpj.slice(0, 12)) === cnpj.slice(12);
}

export function paraCnpj(valor: string): Cnpj {
  const cnpj = limparCnpj(valor);
  if (!ehCnpj(cnpj)) throw new TypeError(`CNPJ inválido: ${valor}`);
  return cnpj;
}

Testes e integração com o framework

zod / class-validator
// Zod
import { z } from 'zod';
import { ehCnpj } from './cnpj';

export const esquemaEmpresa = z.object({
  razaoSocial: z.string().min(3),
  cnpj: z.string().refine(ehCnpj, { message: 'CNPJ inválido' }),
});

// class-validator
import { registerDecorator, ValidationOptions } from 'class-validator';

export function EhCnpj(opcoes?: ValidationOptions) {
  return (alvo: object, propriedade: string) => {
    registerDecorator({
      name: 'ehCnpj',
      target: alvo.constructor,
      propertyName: propriedade,
      options: opcoes,
      validator: {
        validate: (valor: unknown) => typeof valor === 'string' && ehCnpj(valor),
        defaultMessage: () => 'CNPJ inválido',
      },
    });
  };
}

Detalhes que costumam quebrar em TypeScript

Casos de teste recomendados

Cubra pelo menos estes cenários — eles pegam praticamente todos os erros de implementação:

EntradaEsperadoO que testa
12.ABC.345/01DE-35válidoexemplo oficial, com máscara
12abc34501de35válidonormalização para maiúsculas
11.222.333/0001-81válidocompatibilidade com o formato numérico
11.222.333/0001-82inválidodígito verificador errado
12ABC34501DEABinválidoletra no dígito verificador
12ABC34501DE3inválidotamanho incorreto
00.000.000/0000-00inválidosequência repetida
"" / nullinválidoentrada vazia sem exceção

Precisa de mais massa de teste? O gerador produz até 500 CNPJs alfanuméricos válidos de uma vez, com opção de baixar em .txt.

O mesmo algoritmo em outras linguagens

Dúvidas sobre CNPJ alfanumérico em TypeScript

Preciso de alguma biblioteca para validar CNPJ alfanumérico em TypeScript?

Não. O código desta página usa apenas a biblioteca padrão de TypeScript — são cerca de 30 linhas. Bibliotecas de terceiros só valem a pena se você também precisa de formatação, geração e validação de outros documentos; e, nesse caso, confira se a versão instalada já suporta o formato alfanumérico.

A mesma função valida CNPJ numérico e alfanumérico em TypeScript?

Sim. Como o valor de cada dígito é o próprio dígito (código ASCII menos 48), o algoritmo alfanumérico produz o mesmo resultado do antigo para números. Você não precisa manter duas funções nem ramificar por formato.

Como testar se a implementação está certa?

Use o exemplo oficial da Receita Federal: a base 12ABC34501DE tem dígitos verificadores 35, formando 12.ABC.345/01DE-35. Confira também um CNPJ numérico conhecido, como 11.222.333/0001-81, e um inválido, como 11.222.333/0001-82.

O que mais precisa mudar além da função de validação?

O tipo da coluna no banco (de numérico para VARCHAR(14)), qualquer conversão para inteiro no caminho do dado, as máscaras de entrada e as regex espalhadas por validações e relatórios. A função de validação costuma ser a parte mais fácil da migração.