Skip to content

Instantly share code, notes, and snippets.

@joaohcrangel
Last active October 14, 2025 00:37
Show Gist options
  • Select an option

  • Save joaohcrangel/8bd48bcc40b9db63bef7201143303937 to your computer and use it in GitHub Desktop.

Select an option

Save joaohcrangel/8bd48bcc40b9db63bef7201143303937 to your computer and use it in GitHub Desktop.
Função para validar CPF em TypeScript
function isValidCPF(value: string) {
if (typeof value !== 'string') {
return false;
}
value = value.replace(/[^\d]+/g, '');
if (value.length !== 11 || !!value.match(/(\d)\1{10}/)) {
return false;
}
const values = value.split('').map(el => +el);
const rest = (count) => (values.slice(0, count-12).reduce( (soma, el, index) => (soma + el * (count-index)), 0 )*10) % 11 % 10;
return rest(10) === values[9] && rest(11) === values[10];
}
@bestknighter
Copy link

Precisei dessa função novamente em outro projeto. Só que nele eu tbm precisava da função que gerava o dígito verificador em outros lugares do código. Lá eu transformei ela num método funcional puro e extraí para o mesmo módulo. Apliquei a mesma mudança aqui mas mantive dentro da função para não poluir o escopo.

function isValidCPF(value: string) {
    // Se não for string, o CPF é inválido
    if (typeof value !== 'string') {
        return false;
    }

    // Remove todos os caracteres que não sejam números
    value = value.replace(/[^\d]+/g, '');

    // Se o CPF não tem 11 dígitos ou todos os dígitos são repetidos, o CPF é inválido
    if (value.length !== 11 || !!value.match(/(\d)\1{10}/)) {
        return false;
    }
    
    // Transforma de string para number[] com cada dígito sendo um número no array
    const digits = value.split('').map(el => +el);

    // Função que calcula o dígito verificador de acordo com a fórmula da Receita Federal
    function getVerifyingDigit(arr: number[]) {
        const reduced = arr.reduce( (sum, digit, index)=>(sum + digit * (arr.length - index + 1)), 0 );
        return (reduced * 10) % 11 % 10;
    }

    // O CPF é válido se, e somente se, os dígitos verificadores estão corretos
    return getVerifyingDigit(digits.slice(0, 9)) === digits[9]
        && getVerifyingDigit(digits.slice(0, 10)) === digits[10];
}

@flourigh
Copy link

flourigh commented Jun 6, 2025

Há uma falha nessa função. Ela aceita os CPFs 11111111111, 22222222222, ..., 99999999999 como válidos.

Sugestão:

function isValidCPF(cpf) {
    if (typeof cpf !== "string") return false
    cpf = cpf.replace(/[\s.-]*/igm, '')
    if (
        !cpf ||
        cpf.length != 11 ||
        cpf == "00000000000" ||
        cpf == "11111111111" ||
        cpf == "22222222222" ||
        cpf == "33333333333" ||
        cpf == "44444444444" ||
        cpf == "55555555555" ||
        cpf == "66666666666" ||
        cpf == "77777777777" ||
        cpf == "88888888888" ||
        cpf == "99999999999" 
    ) {
        return false
    }
    var soma = 0
    var resto
    for (var i = 1; i <= 9; i++) 
        soma = soma + parseInt(cpf.substring(i-1, i)) * (11 - i)
    resto = (soma * 10) % 11
    if ((resto == 10) || (resto == 11))  resto = 0
    if (resto != parseInt(cpf.substring(9, 10)) ) return false
    soma = 0
    for (var i = 1; i <= 10; i++) 
        soma = soma + parseInt(cpf.substring(i-1, i)) * (12 - i)
    resto = (soma * 10) % 11
    if ((resto == 10) || (resto == 11))  resto = 0
    if (resto != parseInt(cpf.substring(10, 11) ) ) return false
    return true
}
  if (/^(\d)\1+$/.test(CPF)) {
    return false;
  }

@felipe-sbm
Copy link

Tenho uma sugestão usando paradigma funcional, e um pouco mais reduzido 🤓

function isValidCPF(cpf) {
    if (typeof cpf !== 'string') return false
    cpf = cpf.replace(/[^\d]+/g, '')
    if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false
    cpf = cpf.split('')
    const validator = cpf
        .filter((digit, index, array) => index >= array.length - 2 && digit)
        .map( el => +el )
    const toValidate = pop => cpf
        .filter((digit, index, array) => index < array.length - pop && digit)
        .map(el => +el)
    const rest = (count, pop) => (toValidate(pop)
        .reduce((soma, el, i) => soma + el * (count - i), 0) * 10) % 11 % 10
    return !(rest(10,2) !== validator[0] || rest(11,1) !== validator[1])
}

Pra quem quer entender:

function isValidCPF(cpf) {
    // Validar se é String
    if (typeof cpf !== 'string') return false
    
    // Tirar formatação
    cpf = cpf.replace(/[^\d]+/g, '')
    
    // Validar se tem tamanho 11 ou se é uma sequência de digitos repetidos
    if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false
    
    // String para Array
    cpf = cpf.split('')
    
    const validator = cpf
        // Pegar os últimos 2 digitos de validação
        .filter((digit, index, array) => index >= array.length - 2 && digit)
        // Transformar digitos em números
        .map( el => +el )
        
    const toValidate = pop => cpf
        // Pegar Array de items para validar
        .filter((digit, index, array) => index < array.length - pop && digit)
        // Transformar digitos em números
        .map(el => +el)
    
    const rest = (count, pop) => (toValidate(pop)
        // Calcular Soma dos digitos e multiplicar por 10
        .reduce((soma, el, i) => soma + el * (count - i), 0) * 10) 
        // Pegar o resto por 11
        % 11 
        // transformar de 10 para 0
        % 10
        
    return !(rest(10,2) !== validator[0] || rest(11,1) !== validator[1])
}

Esta função já retorna um booleano (verdadeiro ou falso), logo não precisa comparar dentro de um condicional (if)... só chamar a função!

if ( isValidCPF(cpf) ) // só executa se for cpf válido
if ( !isValidCPF(cpf) ) // só executa se não for um cpf válido

Essa foi lendária!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment