Overview
Type is a singleton (new TypeManager()) exported from @bitrix24/b24jssdk. Every method (other than getTag and clone) is a TypeScript type guard, so you can use it in if chains and have the compiler narrow the value:
import { Type } from '@bitrix24/b24jssdk'
function process(value: unknown) {
if (Type.isStringFilled(value)) {
// value: string
return value.trim()
}
if (Type.isPlainObject(value)) {
// value: Record<string | number, any>
}
}
The guards are grouped by the kind of value they check:
- Strings — non-empty string checks.
- Numbers / Booleans — number, integer, float, boolean.
- Objects / Functions — plain objects, functions,
Map/Set/WeakMap/WeakSet,RegExp, prototypes,null/undefined. - Arrays — arrays, array-like values, typed arrays,
ArrayBuffer. - DOM — nodes, element nodes, text nodes.
- Files —
Blob,File,FormData. - JSON-RPC — request / response message shapes.
- Other —
getTag(raw[[Class]]tag) andclone(deep clone).
Method Signature
Strings
Numbers / Booleans
Objects / Functions
Arrays
DOM
Files / Blobs / FormData
JSON-RPC
Other
getTag(value: any): string // Object.prototype.toString.call(value)
clone(obj: any, bCopyObj?: boolean): any // deep clone; bCopyObj defaults to true
Key Concepts
isJsonRpcRequest/isJsonRpcResponseare plainbooleanpredicates, not type guards. Every other method in this class narrows withvalue is X; these two intentionally (or not) returnboolean, so using them in anifdoes not narrowvalue's type.isObjectLike<T>narrows to a caller-supplied generic, not toobject. It only checkstypeof value === 'object' && value !== null; theTyou pass is not verified at runtime — arrays,Map,Date, and DOM nodes all pass.isPlainObjectis the stricter check when you specifically want a{}-style object.isArrayLikealso matches strings. Strings have a numericlengthand are not functions, soType.isArrayLike('abc')istrue. UseisArraywhen you need a real array.isDomNoderequires a real DOM global.isElementNode/isTextNodedereference the globalNodeconstant, so they only work in a browser (or JSDOM) environment — calling them in plain Node.js without a DOM shim throws aReferenceError.clonemutates nothing in the source, but only clones plain data shapes it recognises. Arrays and plain objects are copied key-by-key (recursively unlessbCopyObjisfalse),Dateis rebuilt vianew Date(obj), and DOM nodes go throughNode.cloneNode(bCopyObj). Anything else withtypeof obj === 'object'falls into the generic branch and is rebuilt vianew obj.constructor(), so custom classes with required constructor arguments can throw.
Error Handling
The guard methods never throw for the value they inspect — a non-matching, null, or undefined value simply yields false. The exceptions are environment-dependent: isElementNode / isTextNode dereference the global Node constant and throw a ReferenceError outside a DOM environment, and clone can throw when it falls back to new obj.constructor() for a class that requires constructor arguments. Guard those calls when running server-side or when cloning arbitrary class instances.
Examples
Narrowing with string and object guards:
import { Type } from '@bitrix24/b24jssdk'
function describe(value: unknown): string {
if (Type.isStringFilled(value)) {
return `string: ${value.trim()}`
}
if (Type.isPlainObject(value)) {
return `object with ${Object.keys(value).length} keys`
}
if (Type.isArrayFilled(value)) {
return `array with ${value.length} items`
}
return 'unknown'
}
describe(' hi ') // 'string: hi'
describe({ a: 1 }) // 'object with 1 keys'
describe([1, 2, 3]) // 'array with 3 items'
Tag-based checks and getTag:
import { Type } from '@bitrix24/b24jssdk'
Type.getTag([1, 2, 3]) // '[object Array]'
Type.getTag(new Map()) // '[object Map]'
Type.getTag(/abc/) // '[object RegExp]'
Type.isMap(new Map()) // true
Type.isSet(new Set()) // true
Type.isRegExp(/abc/) // true
JSON-RPC message shapes:
import { Type } from '@bitrix24/b24jssdk'
Type.isJsonRpcRequest({ jsonrpc: '2.0', method: 'ping', id: 1 }) // true
Type.isJsonRpcRequest({ jsonrpc: '2.0' }) // false, no `method`
Type.isJsonRpcResponse({ jsonrpc: '2.0', id: 1, result: { ok: true } }) // true
Type.isJsonRpcResponse({ jsonrpc: '2.0', id: 1 }) // false, no `result`/`error`
Deep cloning with clone:
import { Type } from '@bitrix24/b24jssdk'
const original = { a: 1, nested: { b: 2 } }
const deep = Type.clone(original)
deep.nested.b = 99
console.log(original.nested.b) // 2 — untouched, deep clone
const shallow = Type.clone(original, false)
shallow.nested.b = 42
console.log(original.nested.b) // 42 — same nested reference, shallow clone
Alternatives and Recommendations
- Prefer the type-guard methods (
value is X) over manualtypeof/instanceofchecks. They read the same but also narrow the value's TypeScript type inside theifbranch, which the twoboolean-returning JSON-RPC checks do not. - Use
isPlainObjectinstead ofisObjectwhen you need a{}-style record.isObjectalso accepts functions, andisObjectLikeaccepts arrays,Map,Date, and DOM nodes —isPlainObjectis the only one of the three that excludes all of those. isTypedArraycovers the nine concrete typed-array views, notDataView. It matchesInt8Array…Float64Arraybut returnsfalsefor aDataView; useArrayBuffer.isView(value)when you want to includeDataViewas well.- String/number coercion and formatting live in
Text.Typeonly checks shapes; reach forText.toNumber/Text.toInteger/Text.toBooleanwhen you need to convert a value rather than just test it. cloneis a general-purpose deep clone, not a structured-clone replacement. For values you control (plain data returned from the REST API) it is sufficient; forMap/Set/ArrayBufferpayloads or values that require exact prototype fidelity, preferstructuredClone(where available) or a dedicated cloning library.
Text
Text and date utilities — UUID v4 / v7, encode / decode HTML entities, type conversions, case helpers, Luxon-backed `toDateTime` / `toB24Format`, number formatting, and query-string builder.
useFormatter
Composable that returns shared `FormatterNumbers` and `FormatterIban` instances pre-configured with country specifications.