JavaScript provides two operators for typechecking:
typeof is used to typecheck for primitive valuesinstanceof is used to typecheck for class instances
Primitive values can’t leverage the instanceof operator,
which is a bit of a letdown. To make matters worse, JavaScript’s built-in
objects such as Boolean, String and
Number can only be used with instanceof to check
for instances created using the corresponding constructor. Moreover,
typeof has a few quirks that further complicate matters, such
as typeof null returning 'object'.
Yet, there’s still hope to use instanceof for primitive
values.
Symbol.hasInstance
allows us to customize the behavior of the
instanceof operator. But, in order to do that, we need to
define a class for each primitive type. Here’s what this
looks like:
class PrimitiveNumber {
static [Symbol.hasInstance] = x => typeof x === 'number';
}
123 instanceof PrimitiveNumber; // true
class PrimitiveString {
static [Symbol.hasInstance] = x => typeof x === 'string';
}
'abc' instanceof PrimitiveString; // true
class PrimitiveBoolean {
static [Symbol.hasInstance] = x => typeof x === 'boolean';
}
false instanceof PrimitiveBoolean; // true
class PrimitiveSymbol {
static [Symbol.hasInstance] = x => typeof x === 'symbol';
}
Symbol.iterator instanceof PrimitiveSymbol; // true
class PrimitiveNull {
static [Symbol.hasInstance] = x => x === null;
}
null instanceof PrimitiveNull; // true
class PrimitiveUndefined {
static [Symbol.hasInstance] = x => x === undefined;
}
undefined instanceof PrimitiveUndefined; // true