Last active
May 14, 2018 00:06
-
-
Save devsnek/a99cd87a85644224255ef111ef3afebb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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