Skip to content

Instantly share code, notes, and snippets.

@guiseek
Created December 15, 2023 23:17
Show Gist options
  • Save guiseek/da52933c5b6b17438d85b91e304df777 to your computer and use it in GitHub Desktop.
Save guiseek/da52933c5b6b17438d85b91e304df777 to your computer and use it in GitHub Desktop.
Text State
import {determineValue} from './utilities'
import type {Primitive} from './types'
export class Bit<T extends Primitive> extends Text {
constructor(public initialValue: T) {
super(initialValue.toLocaleString())
}
set = (value: T) => {
this.textContent = value.toLocaleString()
}
get value() {
const {textContent, initialValue} = this
const value = textContent ?? initialValue
return determineValue<T>(value as T) as T
}
}
import type {TypedBit} from './types'
import {Bit} from './bit'
export function mapper<T extends object>(obj: T) {
const transformed = {} as Record<string, unknown>
for (const [key, value] of Object.entries(obj)) {
const isDate = value instanceof Date
const isString = typeof value === 'string'
const isNumber = typeof value === 'number'
const isObject = typeof value === 'object'
const isValue = isDate || isString || isNumber
transformed[key] = !isValue && isObject ? mapper(value) : new Bit(value)
}
return Array.isArray(obj)
? Object.values(transformed)
: (transformed as TypedBit<T>)
}
import {mapper} from './mapper'
export function state<T extends object>(initialValue: T) {
return mapper<T>(initialValue)
}
import {Bit} from './bit'
export type Primitive = string | number | Date
export type DetectBit<T> = T extends Array<infer U>
? Array<DetectBit<U>>
: T extends Primitive
? Bit<T>
: T extends object
? TypedBit<T>
: null
export type TypedBit<T> = {
[K in keyof T]: DetectBit<T[K]>
}
import type {Primitive} from './types'
export function determineValue<T extends Primitive>(value: T): T | null {
if (!isNaN(+value)) return +value as T
if (!isNaN(new Date(value).getTime())) return new Date(value) as T
if (typeof value === 'string') return value as T
return null
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment