This commit is contained in:
+14
-6
@@ -1,10 +1,18 @@
|
||||
export type JsonValue = JsonValue[] | boolean | null | number | string | { [key: string]: JsonValue }
|
||||
|
||||
export function isJsonValue(value: unknown): value is JsonValue {
|
||||
if (value === null) return true
|
||||
if (typeof value === 'boolean' || typeof value === 'string') return true
|
||||
if (typeof value === 'number') return Number.isFinite(value)
|
||||
if (Array.isArray(value)) return [...value].every(isJsonValue)
|
||||
if (typeof value === 'object') return Object.values(value).every(isJsonValue)
|
||||
return false
|
||||
const pending: unknown[] = [value]
|
||||
while (pending.length > 0) {
|
||||
const item = pending.pop()
|
||||
if (item === null || typeof item === 'boolean' || typeof item === 'string') continue
|
||||
if (typeof item === 'number') {
|
||||
if (!Number.isFinite(item)) return false
|
||||
continue
|
||||
}
|
||||
// A hole is not a JSON value, and Array.prototype methods skip holes — spreading materialises them.
|
||||
if (Array.isArray(item)) pending.push(...item)
|
||||
else if (typeof item === 'object') pending.push(...Object.values(item))
|
||||
else return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user