Skip to content

Instantly share code, notes, and snippets.

@denysdovhan
Forked from chicoxyzzy/noncoercible.js
Created February 18, 2017 18:32
Show Gist options
  • Save denysdovhan/3d8d321d6fc766dfe212bfc341ec0ba7 to your computer and use it in GitHub Desktop.
Save denysdovhan/3d8d321d6fc766dfe212bfc341ec0ba7 to your computer and use it in GitHub Desktop.
Non-coercible objects
function nonCoercible(val) {
if (val == null) {
throw TypeError('nonCoercible shouldn\'t be called with null or undefined');
}
const res = Object(val);
res[Symbol.toPrimitive] = () => {
throw TypeError('Trying to coerce non-coercible object');
}
return res;
};
// USAGE
// objects
const foo = nonCoercible({foo: 'foo'});
foo * 10; // throws TypeError: Trying to coerce non-coercible object
foo + 'evil'; // throws TypeError: Trying to coerce non-coercible object
nonCoercible(['foo'])[0]; // "foo"
// Be sure you understend how it works for Number, String, Boolean and Symbol types
// You should cast value using `toString` or `valueOf` when you want to use it with primitive types
// Remember that nonCoercible always returns an object
// strings
const bar = nonCoercible('bar');
bar + '1'; // throws TypeError: Trying to coerce non-coercible object
bar.toString() + 1; // bar1
bar === 'bar'; // false
bar.toString() === 'bar'; // true
bar == 'bar'; // throws TypeError: Trying to coerce non-coercible object
// numbers
const baz = nonCoercible(1);
baz == 1; // throws TypeError: Trying to coerce non-coercible object
baz === 1; // false
baz.valueOf() === 1; // true
// booleans
const qux = nonCoercible(true);
qux == true; // throws TypeError: Trying to coerce non-coercible object
qux === true; // false
qux.valueOf() === true; // true
// symbols
const xyzzy = Symbol('xyzzy');
const courge = nonCoercible(xyzzy);
courge === xyzzy; // false
courge.valueOf() === xyzzy; // true
courge == xyzzy; // true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment