Skip to content

Instantly share code, notes, and snippets.

@nyteshade
Created May 29, 2026 04:52
Show Gist options
  • Select an option

  • Save nyteshade/48464f705e471269ba40ea94a7fe322c to your computer and use it in GitHub Desktop.

Select an option

Save nyteshade/48464f705e471269ba40ea94a7fe322c to your computer and use it in GitHub Desktop.
TypedNumber
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