@xylabs/typeof
Version:
Base functionality used throughout XY Labs TypeScript/JavaScript libraries
67 lines (56 loc) • 1.73 kB
text/typescript
import { isType } from './isType.ts'
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
export type TypedValue = bigint | string | number | boolean | null | TypedObject | TypedArray | Function | symbol | undefined
export type TypedKey<T extends string | void = void> = T extends string ? T : string | number | symbol
export type TypedObject = { [key: TypedKey]: TypedValue } | object
export type TypedArray = TypedValue[]
export const isTypedKey = (value: unknown): value is TypedKey => {
switch (typeof value) {
case 'string':
case 'bigint':
case 'number':
case 'symbol': {
return true
}
default: {
return false
}
}
}
export const isTypedValue = (value: unknown): value is TypedValue => {
switch (typeof value) {
case 'string':
case 'number':
case 'boolean': {
return true
}
default: {
return value === null || isTypedObject(value) || isTypedArray(value)
}
}
}
export const isTypedArray = (value: unknown): value is TypedArray => {
return Array.isArray(value) && !value.some(item => !isTypedValue(item))
}
export const isValidTypedFieldPair = (pair: [key: unknown, value: unknown]): pair is [key: TypedKey, value: TypedValue] => {
const [key, value] = pair
return isTypedKey(key) && isTypedValue(value)
}
export const isTypedObject = (value: unknown): value is TypedObject => {
return (
isType(value, 'object')
// check if all keys are strings
&& !Object.entries(value as object).some(item => !isValidTypedFieldPair(item))
)
}
// Object Type Test
/*
interface TestObject {
value: number
}
const x: TestObject = { value: 1 }
const f = (p: TypedValue): void => {
console.log(p)
}
f(x)
*/