Skip to content

Instantly share code, notes, and snippets.

@chicoxyzzy
Last active March 15, 2021 17:09
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chicoxyzzy/5dd24608e886adf5444499896dff1197 to your computer and use it in GitHub Desktop.
Save chicoxyzzy/5dd24608e886adf5444499896dff1197 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 understand 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