···11+/**
22+ * Type guards and combinators for runtime type checking.
33+ *
44+ * @module data/guards
55+ */
66+77+// =============================================================================
88+// Primitive Type Guards
99+// =============================================================================
1010+1111+/** Type guard for string values */
1212+export const isString = (x: unknown): x is string => typeof x === "string"
1313+1414+/** Type guard for number values */
1515+export const isNumber = (x: unknown): x is number => typeof x === "number"
1616+1717+/** Type guard for boolean values */
1818+export const isBoolean = (x: unknown): x is boolean => typeof x === "boolean"
1919+2020+/** Type guard for non-null object values */
2121+export const isObject = (x: unknown): x is object => typeof x === "object" && x !== null
2222+2323+/** Type guard for array values */
2424+export const isArray = (x: unknown): x is unknown[] => Array.isArray(x)
2525+2626+// =============================================================================
2727+// Number Property Guards
2828+// =============================================================================
2929+3030+/** Type guard for positive numbers (x > 0) */
3131+export const isPositive = (x: unknown): x is number => isNumber(x) && x > 0
3232+3333+/** Type guard for negative numbers (x < 0) */
3434+export const isNegative = (x: unknown): x is number => isNumber(x) && x < 0
3535+3636+/** Type guard for integer numbers */
3737+export const isInteger = (x: unknown): x is number => isNumber(x) && Number.isInteger(x)
3838+3939+/** Type guard for finite numbers (excludes Infinity and NaN) */
4040+export const isFiniteNumber = (x: unknown): x is number => isNumber(x) && Number.isFinite(x)
4141+4242+// =============================================================================
4343+// Guard Combinators
4444+// =============================================================================
4545+4646+/** Combines two guards with logical AND - both must pass */
4747+export const and = <A, B extends A, C extends B>(
4848+ g1: (x: A) => x is B,
4949+ g2: (x: B) => x is C
5050+) => (x: A): x is C => g1(x) && g2(x)
5151+5252+/** Combines two guards with logical OR - either must pass */
5353+export const or = <A, B extends A, C extends A>(
5454+ g1: (x: A) => x is B,
5555+ g2: (x: A) => x is C
5656+) => (x: A): x is B | C => g1(x) || g2(x)
5757+5858+/** Negates a guard */
5959+export const not = <A, B extends A>(
6060+ guard: (x: A) => x is B
6161+) => (x: A): x is Exclude<A, B> => !guard(x)
6262+6363+// =============================================================================
6464+// Property Guards
6565+// =============================================================================
6666+6767+/** Creates a guard that checks if an object has a specific property */
6868+export const hasProperty = <K extends string>(key: K) =>
6969+ <T>(x: T): x is T & Record<K, unknown> =>
7070+ isObject(x) && key in x
+7
src/data/index.ts
···11+/**
22+ * Data module - Type guards and combinators.
33+ *
44+ * @module data
55+ */
66+77+export * from "./guards"