Created
May 29, 2026 04:52
-
-
Save nyteshade/48464f705e471269ba40ea94a7fe322c to your computer and use it in GitHub Desktop.
TypedNumber
This file contains hidden or 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
| class TypedNumber extends Number { | |
| #number = 0; | |
| #unit = 1; | |
| constructor(number, unit = TypedNumber.PLAIN) { | |
| super(number) | |
| this.#number = number | |
| this.#unit = unit | |
| } | |
| get number() { | |
| return this.#number | |
| } | |
| get unit() { | |
| return this.#unit | |
| } | |
| equals(other) { | |
| return (this - 0) === (other - 0) | |
| } | |
| valueOf() { | |
| if (!isNaN(this.unit)) | |
| return this.#number * this.#unit | |
| return this.#number | |
| } | |
| serialize() { | |
| return { | |
| _type: this.constructor.name, | |
| number: this.number, | |
| unit: this.unit, | |
| } | |
| } | |
| static equals(left, right) { | |
| return (left - 0) === (right - 0) | |
| } | |
| static deserialize(object) { | |
| if (!object || object?._type !== this.name) | |
| return null | |
| return new this(object?.number ?? 0, object?.unit ?? 1) | |
| } | |
| toString() { | |
| return this[Symbol.toPrimitive]('string') | |
| } | |
| [Symbol.toPrimitive](hint = "number") { | |
| if (hint === "string") { | |
| return `${this.valueOf()}` | |
| } | |
| return this.valueOf() | |
| } | |
| [Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) { | |
| const green = value => `\x1b[32m${value}\x1b[39m` | |
| return [ | |
| `${green(this.valueOf())}`, | |
| `[${green(this.#number)}x${green(this.#unit)}]` | |
| ].join(' ') | |
| } | |
| static get PLAIN() { return 1 } | |
| static get MS() { return 1_000 } | |
| static get MILLISECONDS() { return 1_000 } | |
| static get NS() { return 1_000_000 } | |
| static get NANOSECONDS() { return 1_000_000 } | |
| static { | |
| const base = { configurable: true, enumerable: true } | |
| Object.defineProperty(Number.prototype, 'milliseconds', { | |
| get() { return new TypedNumber(this, TypedNumber.MS) }, | |
| ...base | |
| }) | |
| Object.defineProperty(Number.prototype, 'minutes', { | |
| get() { return new TypedNumber(this, TypedNumber.MS * 60) }, | |
| ...base | |
| }) | |
| Object.defineProperty(Number.prototype, 'hours', { | |
| get() { return new TypedNumber(this, TypedNumber.MS * 60 * 60) }, | |
| ...base | |
| }) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment