Skip to content

Instantly share code, notes, and snippets.

@devsnek
Last active May 14, 2018 00:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devsnek/a99cd87a85644224255ef111ef3afebb to your computer and use it in GitHub Desktop.
Save devsnek/a99cd87a85644224255ef111ef3afebb to your computer and use it in GitHub Desktop.
'use strict';
const { isProxy } = require('util').types;
const { getProxyDetails } = process.binding('util');
const hasOwnProperty = (v, n) => Reflect.apply(Object.hasOwnProperty, v, [n]);
Object.defineProperty(Symbol, 'typeOf', {
enumerable: false,
configurable: false,
value: Symbol('Symbol.typeOf'),
});
const AsyncFunction = (async () => {}).constructor;
const GeneratorFunction = (function* x() {}).constructor; // eslint-disable-line no-empty-function
const labels = [
BigInt, 'BigInt',
Boolean, 'Boolean',
Function, 'Function',
Number, 'Number',
Object, 'Object',
String, 'String',
Symbol, 'Symbol',
Array, 'Array',
Int8Array, 'Int8Array',
Int16Array, 'Int16Array',
Int32Array, 'Int32Array',
Uint8Array, 'Uint8Array',
Uint8ClampedArray, 'Uint8ClampedArray',
Uint16Array, 'Uint16Array',
Uint32Array, 'Uint32Array',
BigInt64Array, 'BigInt64Array',
BigUint64Array, 'BigUint64Array',
Float32Array, 'Float32Array',
Float64Array, 'Float64Array',
ArrayBuffer, 'ArrayBuffer',
DataView, 'DataView',
SharedArrayBuffer, 'SharedArrayBuffer',
AsyncFunction, 'AsyncFunction',
GeneratorFunction, 'GeneratorFunction',
Error, 'Error',
EvalError, 'EvalError',
RangeError, 'RangeError',
ReferenceError, 'ReferenceError',
SyntaxError, 'SyntaxError',
TypeError, 'TypeError',
URIError, 'URIError',
Set, 'Set',
Map, 'Map',
WeakMap, 'WeakMap',
WeakSet, 'WeakSet',
Date, 'Date',
Promise, 'Promise',
RegExp, 'RegExp',
WebAssembly.Module, 'WebAssembly Module',
WebAssembly.Instance, 'WebAssembly Instance',
WebAssembly.Memory, 'WebAssembly Memory',
WebAssembly.Table, 'WebAssembly Table',
WebAssembly.CompileError, 'WebAssembly CompileError',
WebAssembly.LinkError, 'WebAssembly LinkError',
WebAssembly.RuntimeError, 'WebAssembly RuntimeError',
];
const kIdentity = Symbol('[[Identity]]');
const kIdentityOnPrototype = Symbol('[[IdentityOnPrototype]]');
for (let i = 0; i < labels.length; i += 2) {
const thisKID = Symbol(labels[i + 1]);
Object.defineProperty(labels[i], kIdentity, {
enumerable: false,
configurable: false,
writable: false,
value: thisKID,
});
Object.defineProperties(labels[i].prototype, {
[Symbol.typeOf]: {
enumerable: false,
configurable: false,
writable: true,
value: labels[i + 1],
},
[kIdentityOnPrototype]: {
enumerable: false,
configurable: false,
writable: false,
value: thisKID,
},
});
}
Reflect.typeOf = (value) => {
if (value == null) {
return undefined;
}
if (isProxy(value)) {
const [target, handler] = getProxyDetails(value);
if (hasOwnProperty(handler, 'typeOf')) {
return handler.typeOf(target);
}
return Reflect.typeOf(target);
}
const type = value[Symbol.typeOf];
if (type != null) {
return type;
}
return undefined;
};
Reflect.is = (value, type) => {
if (value == null || type == null) {
throw new TypeError(`Cannot compare ${value} against ${type}`);
}
if (isProxy(value)) {
const [target, handler] = getProxyDetails(value);
if (hasOwnProperty(handler, 'is')) {
return handler.is(target, type);
}
return Reflect.is(target, type);
}
const typeSymbol = type[kIdentity];
const valueSymbol = value[kIdentityOnPrototype];
return typeSymbol === valueSymbol;
};
'use strict';
Object.defineProperty(Symbol, 'getType', {
enumerable: false,
configurable: false,
value: Symbol('Symbol.getType'),
});
const AsyncFunction = (async () => {}).constructor;
const GeneratorFunction = (function* x() {}).constructor; // eslint-disable-line no-empty-function
const labels = [
BigInt, 'BigInt',
Boolean, 'Boolean',
Function, 'Function',
Number, 'Number',
Object, 'Object',
String, 'String',
Symbol, 'Symbol',
Array, 'Array',
Int8Array, 'Int8Array',
Int16Array, 'Int16Array',
Int32Array, 'Int32Array',
Uint8Array, 'Uint8Array',
Uint8ClampedArray, 'Uint8ClampedArray',
Uint16Array, 'Uint16Array',
Uint32Array, 'Uint32Array',
BigInt64Array, 'BigInt64Array',
BigUint64Array, 'BigUint64Array',
Float32Array, 'Float32Array',
Float64Array, 'Float64Array',
ArrayBuffer, 'ArrayBuffer',
DataView, 'DataView',
SharedArrayBuffer, 'SharedArrayBuffer',
AsyncFunction, 'AsyncFunction',
GeneratorFunction, 'GeneratorFunction',
Error, 'Error',
EvalError, 'EvalError',
RangeError, 'RangeError',
ReferenceError, 'ReferenceError',
SyntaxError, 'SyntaxError',
TypeError, 'TypeError',
URIError, 'URIError',
Set, 'Set',
Map, 'Map',
WeakMap, 'WeakMap',
WeakSet, 'WeakSet',
Date, 'Date',
Promise, 'Promise',
RegExp, 'RegExp',
WebAssembly.Module, 'WebAssembly Module',
WebAssembly.Instance, 'WebAssembly Instance',
WebAssembly.Memory, 'WebAssembly Memory',
WebAssembly.Table, 'WebAssembly Table',
WebAssembly.CompileError, 'WebAssembly CompileError',
WebAssembly.LinkError, 'WebAssembly LinkError',
WebAssembly.RuntimeError, 'WebAssembly RuntimeError',
];
const kType = Symbol('[[Type]]');
for (let i = 0; i < labels.length; i += 2) {
Object.defineProperty(labels[i], Symbol.getType, {
enumerable: false,
configurable: true,
writable: true,
value: (v) => v[kType],
});
Object.defineProperty(labels[i].prototype, kType, {
enumerable: false,
configurable: false,
writable: false,
value: labels[i + 1],
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment