UNPKG

ts-data-objects

Version:

Simple lightweight library for enhancing plain JS objects with TypeScript wrappers enabling easy API data assertion and validation

293 lines (279 loc) 10.1 kB
/** * Type signature for data object constructor functions. * Creates a function that accepts partial data and returns complete typed objects. * @template T - The object type to be constructed * @param [o] - Optional partial input data * @returns A complete object of type T * @category Core Implementation */ declare type DataConstructor<T extends object> = (o?: Expect<T>) => T; /** * Creates a TypeScript type guard function for runtime type validation. * * Generates a type-safe validation function that: * - Performs runtime type checking * - Provides TypeScript type assertions * - Supports partial input validation based on predicate * * * @example * ```typescript * import { dataGuard } from 'ts-data-objects/core' * import { isStr, isNum } from 'ts-data-objects/common' * * type UserData = { * name: string * age: number * verified?: boolean * } * * // Here we define a function predicate, where `o` is the JSON object * // and we expect it to contain the attributes of the types we expect * const isUserData = dataGuard<UserData>(o => ( * isStr(o?.name) && * isNum(o?.age) * )) * * // Usage: * if (isUserData(someData)) { * //TypeScript now knows `someData` is `UserData` * console.log(someData.name) * } * ``` * * @template T - The object type to create a guard for * @param predicate - Validation function that checks type constraints * @returns A type guard function that asserts input is of type T * @category Core Component */ export declare const dataGuard: <T extends object>(predicate: GuardPredicate<T>) => DataObjectGuard<T>; /** * Creates a typed constructor function for data objects with optional default values. * * This function generates a constructor that: * - Enforces TypeScript type safety * - Merges default values with provided data * - Handles partial input data * * * @example * ```typescript * import { dataObject } from 'ts-data-objects/core' * * type UserData = { * name: string * age: number * verified?: boolean * } * * // Here you can optionally define any default values * // that you might want to be included when parsing JSON data * // or just creating JS Object from scratch * const User = dataObject<UserData>({ * name: '', * verified: false * }) * * // Usage: * const user = User({ name: "John", age: 20 }) * // Result: { name: "John", , age: 20, verified: false } * ``` * * Notes: * - Name collision with TS interface is possible and will work * - The constructor performs shallow merge of objects! This means * that nested objects are replaced rather than copied * * --- * * @template T - The object type/interface to create a constructor for * @param [defaultValues] - Optional default values for the object properties * @returns A constructor function that creates objects of type T * @category Core Component */ export declare const dataObject: <T extends object>(defaultValues?: Expect<T>) => DataConstructor<T>; /** * Type signature for type guard functions that provide TypeScript type assertions. * * Note: * - As pure predicate wouldn't be able to have assertion return type `returnValue is SomeType`, the predicates are wrapped in guard assertions * * @template T - The object type to guard * @param [o] - Optional partial input data to check * @returns Type predicate asserting the input is of type T * @category Core Component */ declare type DataObjectGuard<T extends object> = (o?: Expect<T>) => o is T; /** * Creates a type-safe parser that validates and constructs data objects. * * Combines validation and construction into a single function that: * - Validates input data against type constraints * - Constructs a proper typed object if valid * - Handles validation failures * * @example * ```typescript * import { dataParser } from 'ts-data-objects/core' * * type UserData = { * name: string * age: number * verified?: boolean * } * * // ... with defined constructor and data guard ... * * const parseUser = dataParser<UserData>( * 'UserData', * UserData, // constructor from dataObject * isUserData, // guard from dataGuard * ) * * // Usage: * const user = parseUser(someData) // throws if invalid * // If the code continues, it was successfully parsed * console.log(user.name) * ``` * * @template T - The type to parse into * @param dataType - Type name for error messages * @param constructorFunction - Object constructor function (returned by `dataObject()`) * @param guardFunction - Type guard function (returned by `dataGuard()`) * @param [doNotThrow=false] - If true, logs errors instead of throwing * @returns A function that parses unknown data into type T * @category Core Component */ export declare const dataParser: <T extends object>(dataType: string, constructorFunction: DataConstructor<T>, guardFunction: DataObjectGuard<T>, doNotThrow?: boolean) => DataConstructor<T>; /** * Complete object definition combining constructor, guard, and parser functions. * Provides a unified interface for working with typed data objects. * - Combined parts with {@link NamedConstructor}, {@link NamedGuard} and {@link NamedParser} * * @template Type - The object type being defined * @template TypeName - The name to use for generated functions * @category Core Implementation */ declare type DefinedObject<Type extends object, TypeName extends string> = NamedConstructor<Type, TypeName> & NamedGuard<Type, TypeName> & NamedParser<Type, TypeName>; /** * Creates a complete suite of functions for working with typed data objects. * Combines object construction, validation, and parsing into a single definition. * * This function generates: * - A constructor function for creating objects with defaults * - A type guard function for validation * - A parser function for safely handling unknown data * * All functions are named based on the provided type name: * - Constructor: [typeName] * - Guard / Validation: is[typeName] * - Parser: parse[typeName] * * @example * ```typescript * import { defineObject } from 'ts-data-objects/core' * import { isStr, isNum } from 'ts-data-objects/common' * * type UserData = { * name: string * age: number * verified?: boolean * } * * const { * UserData, // Constructor * isUserData, // Type guard * parseUserData // Parser * } = defineObject<UserData>('UserData', { * defaultValues: { verified: false }, * predicate: o => ( * isStr(o?.name) && * isNum(o?.age) * ) * }) * * // Usage: * const user = UserData({ name: 'John', age: 20 }) * * if (isUserData(someData)) { * // TypeScript now knows `someData` is now `UserData` * console.log(someData) * } * * // if the apiData is correct according to UserData guard, the data is validated * try { * const receivedUser = parseUserData(apiData) * } * catch (e: any) { * // Handle the error... * } * ``` * * @template Type - The object type to define * @template TypeName - The name to use for generated functions * @param typeName - Name used to generate function names * @param options - Configuration for the object definition, see {@link DefineObjectParams} * @returns Object containing named constructor, guard, and parser functions * @category Core Implementation */ export declare const defineObject: <Type extends object, TypeName extends string>(typeName: TypeName, options: DefineObjectParams<Type>) => DefinedObject<Type, TypeName>; /** * Configuration parameters for creating a complete data object definition. * * @template T - The type of object being defined * @property [defaultValues] - Optional default values for object properties * @property predicate - Validation function for type checking * @property [doNotThrow] - Whether to suppress validation errors * @category Core Implementation */ declare type DefineObjectParams<T extends object> = { defaultValues?: T; predicate: GuardPredicate<T>; doNotThrow?: boolean; }; /** * A semantic alias for TypeScript's `Partial<T>` utility type. * Makes code more readable by explicitly indicating expected partial input. * * @template T - The type to make partial * @category Common Utils */ declare type Expect<T> = Partial<T>; /** * Type signature for predicate functions that validate JSON objects. * Used to check if a partial object matches expected type constraints. * * @template T - The object type to validate * @param [o] - Optional partial input data to validate * @returns Boolean indicating whether the input satisfies type constraints * @category Core Component */ declare type GuardPredicate<T extends object> = (o?: Expect<T>) => boolean; /** * Creates a named constructor function type using the provided type name. * - Example: For name "User", creates { User: (data?) => UserType } * - Part of {@link DefinedObject}. * @category Core Implementation */ declare type NamedConstructor<Type extends object, TypeName extends string> = { [N in TypeName as `${N}`]: DataConstructor<Type>; }; /** * Creates a named type guard function type with 'is' prefix. * - Example: For name "User", creates { isUser: (data?) => data is UserType } * - Part of {@link DefinedObject}. * @category Core Implementation */ declare type NamedGuard<Type extends object, TypeName extends string> = { [N in TypeName as `is${N}`]: DataObjectGuard<Type>; }; /** * Creates a named parser function type with 'parse' prefix. * - Example: For name "User", creates { parseUser: (data?) => UserType } * - Part of {@link DefinedObject}. * @category Core Implementation */ declare type NamedParser<Type extends object, TypeName extends string> = { [N in TypeName as `parse${N}`]: DataConstructor<Type>; }; export { }