Cleaner Way to Test for Types? I defined a function that multiplies its argument by 3:

coffee&gt; foo = (x) -&gt; x * 3
[Function]


We can call it with an input of 1:

coffee&gt; foo(1)
3


However, when I tried with a non-Number type:

coffee&gt; foo("3")
9


This behavior appears wrong to me since a String cannot be multiplied by a Number.

To fix it, I'd add something like this:

foo = (x) -&gt;
  if typeof x is 'number'
    x * 3
  else
    throw new Error("not a number:"  + x)


Is there a cleaner way to do this in CoffeeScript?
CoffeeScript is, in the end, just JavaScript with a nicer syntax. So the string-interpreted-as-number behavior is expected and normal. You write:


  This behavior appears wrong to me since a String cannot be multiplied by a Number.


Yet, due to type coercion in JavaScript, a string can be multiplied by a number just fine. And, importantly, the result is correct!

Your options with regard to strict type-checking are:


Using typeof and throwing an exception (or handling it some other way), as you do now.
Doing nothing.


You're still writing JavaScript, so option #2 is a valid solution to most type concerns. For instance, most (all?) the functions in the Math object accept numerical strings just as well as numbers.

For other types, the GIGO principle usually applies: Garbage In, Garbage Out. I.e. if the user of your code passes something completely incompatible, like an object, they'll get NaN back. And that's their problem, really. Same as if you do Math.floor({}) or something.

However, if type-checking is absolutely necessary, you can at least slim your code down a bit:

foo = (x) -&gt;
  throw new TypeError unless typeof x is 'number'
  x * 3


Note that the code throws a TypeError, which is more appropriate for this situation, and that, since it throws, execution of the function is halted just as effectively as writing return. So there's no need for if...else branches.

You can generalize it a bit with a function, if you need to do this more often:

assertNumber = (value) -&gt;
  unless typeof value is 'number'
    throw new TypeError("Expected a Number")


Or, better yet, check whether the value is numeric:

assertNumeric = (value) -&gt;
  if isNaN Number(value)
    throw new TypeError("Expected a numeric value")


And use it like so:

foo = (x) -&gt;
  assertNumeric x
  x * 3