/** * Predicate for narrowing a `Record` type, with string, symbol, or number (arrays) keys. * @param value - The value to check * @returns True if the value is a record object */ export function isRecord( value: unknown, ): value is Record { return typeof value === "object" && value !== null; } /** * Predicate for narrowing a non-array/non-null `object` type. * @param value - The value to check * @returns True if the value is an object (not array or null) */ export function isObject(value: unknown): value is object { return typeof value === "object" && value !== null && !Array.isArray(value); } /** * Predicate for narrowing a `number` type. * @param value - The value to check * @returns True if the value is a finite number */ export function isNumber(value: unknown): value is number { return typeof value === "number" && Number.isFinite(value); } /** * Predicate for narrowing a `string` type. * @param value - The value to check * @returns True if the value is a string */ export function isString(value: unknown): value is string { return typeof value === "string"; } /** * Predicate for narrowing a `boolean` type. * @param value - The value to check * @returns True if the value is a boolean */ export function isBoolean(value: unknown): value is boolean { return typeof value === "boolean"; } /** * Helper type to recursively remove `readonly` properties from type `T`. */ export type Mutable = T extends ReadonlyArray ? Mutable[] : T extends object ? ({ -readonly [P in keyof T]: Mutable }) : T; /** * Helper type to recursively add `readonly` properties to type `T`. */ export type Immutable = T extends ReadonlyArray ? ReadonlyArray> : T extends object ? ({ readonly [P in keyof T]: Immutable }) : T;