Solving the type detection problem in javascript

One of the notorious pitfalls of javascript is that it’s not easy to determine types. The typeof operator, which is the native way of retrieving the type of an element, commits the following atrocities:

  • object, array, regex, date and null are all considered object
  • nan, infinity, integer and float are all considered number

I am exaggerating somewhat – the only real atrocity here is to consider null as an object. As for the rest of the simplifications, they are justified by the fact that 1) everything’s an object in javascript; and 2) there’s no different types of numbers in javascript, in contrast to other languages where’s genuine differences between different types of numbers.

However, typeof isn’t all that bad. It appropriately detects the following types: boolean, string, undefined and function.

Justifications aside, you really want to know the type of whatever your functions will receive. The good news is that this can be solved with a type function that is 16 lines long and will work anywhere. It is based on Douglas Crockford’s type function.

function type (value, objectType) {
   var type = typeof value;
   if (type !== 'object' && type !== 'number') return type;
   if (value instanceof Array) return 'array';
   if (type === 'number') {
      if      (isNaN (value))      return 'nan';
      else if (! isFinite (value)) return 'infinity';
      else if (value % 1 === 0)    return 'integer';
      else                         return 'float';
   type = (value).replace ('[object ', '').replace (']', '').toLowerCase ();
   if (type === 'array' || type === 'date' || type === 'null') return type;
   if (type === 'regexp') return 'regex';
   if (objectType) return type;
   return 'object';

type takes a single argument (of any type, naturally) and returns a string which can be any of: naninfinity, integer, float, array, object, regex, date, null, function, boolean, string, and undefined.

If you pass a truthy second argument to type, and input turns out to be an object, type will return the lowercased name of the class of the object (which, for example, can be object for object literals, arguments for arguments pseudo-arrays, and other values for user-created classes).

Here’s a detailed explanation of how the function works.

I use this function in every library I’ve written and every project where I work. I encourage you to try it out.