Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to tell users of my library functions that passed variables are not of the correct type

I'm currently in the creation of a javascript function library. Mainly for my own use, but you can never be sure if someone else ends up using it in their projects, I'm atleast creating it as if that could happen.
Most methods only work if the variables that are passed are of the correct datatype. Now my question is: What is the best way to alert users that the variable is not of the correct type? Should one throw an error like this?

function foo(thisShouldBeAString){ //just pretend that this is a method and not a global function
 if(typeof(thisShouldBeAString) === 'string') {
  throw('foo(var), var should be of type string');
 }
 #yadayada
}

I know that javascript does internal type conversion, but this can create very weird results (ie '234' + 5 = '2345' but '234' * 1 = 234) and this could make my methods do very weird things.

EDIT
To make things extra clear: I do not wish to do type conversion, the variables passed should be of the correct type. What is the best way to tell the user of my library that the passed variables are not of the correct type?

like image 908
Pim Jager Avatar asked Jan 10 '09 13:01

Pim Jager


2 Answers

The problem with type checking is that its actually quite hard to do. For example:-

var s = new String("Hello World!");
alert(typeof s);

What gets alerted? Ans: "object". Its true its a daft way to initialise a string but I see it quite often none-the-less. I prefer to attempt conversions where necessary or just do nothing.

Having said that in a Javascript environment in which I have total control (which is not true if you are simply providing a library) I use this set of prototype tweaks:-

String.prototype.isString = true;
Number.prototype.isNumber = true;
Boolean.prototype.isBoolean = true;
Date.prototype.isDate = true;
Array.prototype.isArray = true;

Hence testing for the common types can be as simple as:-

if (x.isString)

although you still need to watch out for null/undefined:-

if (x != null && x.isString)

In addition to avoiding the new String("thing") gotcha, this approach particularly comes into its own on Dates and Arrays.

like image 105
AnthonyWJones Avatar answered Sep 27 '22 23:09

AnthonyWJones


Some small remarks on type checking - it's actually not that complicated:

Use typeof to check for primitives and instanceof to check for specific object types.

Example: Check for strings with

typeof x === 'string'

or

typeof x === 'string' || x instanceof String

if you want to include string objects.

To check for arrays, just use

x instanceof Array

This should work reasonably well (there are a few known exceptions - eg Firefox 3.0.5 has a bug where window instanceof Object === false although window.__proto__ instanceof Object === true).

edit: There are some further problems with detection of function objects:

In principle, you could both use typeof func === 'function' and func instanceof Function.

The catch is that in an unnamed browser from a big corporation these checks return the wrong results for some predefined functions (their type is given as 'object'). I know of no workaround for this - the checks only work reliably for user-defined functions...

edit2: There are also problems with objects passed from other windows/frames, as they will inherit from different global objects - ie instanceof will fail. Workarounds for built-in objects exists: For example, you can check for arrays via Object.prototype.toString.call(x) === '[object Array]'.

like image 27
Christoph Avatar answered Sep 27 '22 23:09

Christoph