Como verificar o tipo de variável em JavaScript

JavaScript é fracamente tipado e dinâmico: o tipo pertence ao valor, não à variável. Valores são divididos em duas categorias:
- Primitivos: sem métodos ou propriedades —
string
,number
,bigint
,boolean
,undefined
,symbol
enull
. - Objetos: estruturas que têm métodos/propriedades — exemplos:
Array
,Date
,Function
etc.
Primitivos como string
, number
, boolean
, bigint
e symbol
recebem um wrapper object temporário quando você acessa um método, por exemplo 'foo'.includes('o')
. Já null
e undefined
não têm wrappers — acessar algo neles gera erro.
Técnicas de checagem de tipo
1. typeof
Retorna uma string com o tipo do valor:
Valor | typeof valor |
---|---|
"texto" | "string" |
42 | "number" |
123n | "bigint" |
true | "boolean" |
undefined | "undefined" |
Symbol() | "symbol" |
function(){} | "function" |
{} , [] , new Date() | "object" |
null | "object" (bug histórico) |
Exemplo aprimorado:
function logTipo(x) {
console.log(
x === null ? 'null' :
Array.isArray(x) ? 'array' :
typeof x
);
}
logTipo(null); // "null"
logTipo([1,2,3]); // "array"
logTipo({}); // "object"
logTipo(123); // "number"
2. instanceof
Verifica se um objeto surge de um dado construtor:
const hoje = new Date();
console.log(hoje instanceof Date); // true
console.log(hoje instanceof Object); // true
Atenção: instanceof
falha para null
/undefined
e pode ser enganado caso alguém sobrescreva Symbol.hasInstance
.
3. constructor
Todo objeto possui a propriedade constructor
apontando para sua função construtora:
const arr = [];
console.log(arr.constructor === Array); // true
Mas cuidado: isso pode falhar se alguém alterar o protótipo ou constructor
.
4. Object.prototype.toString.call()
Esta técnica padrão retorna uma string do formato "[object Tipo]"
, confiável para tipos embutidos:
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call(new Date())); // "[object Date]"
console.log(Object.prototype.toString.call(/regex/)); // "[object RegExp]"
Mesmo isso pode ser alterado se alguém usar Symbol.toStringTag
.
Qual usar e quando?
typeof
: perfeito para primitivos e funções.Array.isArray()
: reconhece arrays especificamente, poistypeof []
retorna"object"
.instanceof
econstructor
: úteis para objetos criados por construtores, mas não confiáveis se houver alteração de protótipos.Object.prototype.toString.call()
: mais robusto para tipos internos, comoDate
,RegExp
,Map
etc.
Exemplo prático aprimorado: função de validação de tipo
function getTipo(x) {
if (x === null) return 'null';
if (x === undefined) return 'undefined';
if (Array.isArray(x)) return 'array';
const t = typeof x;
if (t !== 'object') return t;
const tag = Object.prototype.toString.call(x);
return tag.slice(8, -1).toLowerCase(); // exemplo: "[object Date]" => "date"
}
// Testes:
[
null, undefined,
123, 123n, 'abc', true, Symbol(),
[], {}, new Date(), function(){}, /a/i
].forEach(item => {
console.log(item, '->', getTipo(item));
});
Saída esperada:
null -> null
undefined -> undefined
123 -> number
123n -> bigint
"abc" -> string
true -> boolean
Symbol() -> symbol
[] -> array
{} -> object
Date {...} -> date
function (){} -> function
/a/i -> regexp
Dicas adicionais
- Combine técnicas para uma checagem completa (como fizemos com
getTipo
). - Quando precisar de tipagem estática mais segura, considere usar TypeScript.
- Em tempo de execução, use validações de tipo para evitar erros inesperados.
Dica Final
- JavaScript é dinamicamente tipado — o tipo pertence ao valor, não à variável.
- Para valores primitivos, use
typeof
. - Para arrays, prefira
Array.isArray()
(mais preciso quetypeof
). - Para objetos complexos como
Date
,RegExp
,Map
, useObject.prototype.toString.call()
. instanceof
econstructor
funcionam com objetos criados por construtores, mas podem falhar se o protótipo for alterado.- Combine técnicas para garantir precisão, especialmente em bibliotecas ou validações robustas.
- Para aplicações maiores ou críticas, considere usar TypeScript, que oferece tipagem estática segura.
Crie funções reutilizáveis como getTipo()
para identificar qualquer tipo de valor com confiança.