or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

field-registration.mdform-actions.mdform-creation.mdindex.mdstate-management.mdutilities.mdvalidation.md
tile.json

utilities.mddocs/

Utilities

Utility functions and constants for deep object manipulation, form state management, and error handling in Final Form applications.

Capabilities

Deep Object Manipulation

Utility functions for safely getting and setting nested object properties using dot notation and array syntax.

/**
 * Safely retrieves nested values from objects using dot notation or array syntax
 * @param state - Object to retrieve value from
 * @param complexKey - Path to the value using dot notation (e.g., "user.address.city" or "items[0].name")
 * @returns The value at the specified path, or undefined if path doesn't exist
 */
function getIn(state: object, complexKey: string): any;

/**
 * Immutably sets nested values in objects using dot notation or array syntax
 * @param state - Object to set value in
 * @param key - Path where to set the value using dot notation (e.g., "user.address.city" or "items[0].name")
 * @param value - Value to set at the specified path
 * @param destroyArrays - Whether to remove array elements when setting undefined (default: false)
 * @returns New object with the value set at the specified path
 */
function setIn(
  state: object,
  key: string,
  value: any,
  destroyArrays?: boolean
): object;

Usage Examples:

import { getIn, setIn } from "final-form";

// Getting nested values
const user = {
  profile: {
    name: 'John Doe',
    address: {
      city: 'New York',
      coordinates: [40.7128, -74.0060]
    }
  },
  preferences: {
    theme: 'dark',
    notifications: true
  }
};

// Simple nested access
const userName = getIn(user, 'profile.name'); // 'John Doe'
const city = getIn(user, 'profile.address.city'); // 'New York'
const theme = getIn(user, 'preferences.theme'); // 'dark'

// Array access
const latitude = getIn(user, 'profile.address.coordinates[0]'); // 40.7128
const longitude = getIn(user, 'profile.address.coordinates[1]'); // -74.0060

// Safe access - returns undefined for non-existent paths
const missing = getIn(user, 'profile.address.country'); // undefined
const deepMissing = getIn(user, 'profile.social.twitter.handle'); // undefined

// Setting nested values
const initialState = {
  users: [],
  config: {
    theme: 'light'
  }
};

// Set simple nested value
const newState1 = setIn(initialState, 'config.theme', 'dark');
// Result: { users: [], config: { theme: 'dark' } }

// Set array values
const newState2 = setIn(newState1, 'users[0]', { id: 1, name: 'Alice' });
// Result: { users: [{ id: 1, name: 'Alice' }], config: { theme: 'dark' } }

// Set nested object in array
const newState3 = setIn(newState2, 'users[0].profile.email', 'alice@example.com');
// Result: { users: [{ id: 1, name: 'Alice', profile: { email: 'alice@example.com' } }], config: { theme: 'dark' } }

// Remove values by setting undefined
const newState4 = setIn(newState3, 'config.theme', undefined);
// Result: { users: [...], config: {} }

// Destroy arrays when setting undefined
const arrayState = { items: ['a', 'b', 'c'] };
const withoutDestroy = setIn(arrayState, 'items[1]', undefined, false);
// Result: { items: ['a', undefined, 'c'] }

const withDestroy = setIn(arrayState, 'items[1]', undefined, true);
// Result: { items: ['a', 'c'] }

Form Error Constants

Special constants for handling form-level and array-level errors.

/** Special key for form-level errors */
const FORM_ERROR: string;

/** Special key for array field errors */
const ARRAY_ERROR: string;

Usage Examples:

import { createForm, FORM_ERROR, ARRAY_ERROR } from "final-form";

// Form-level error handling
const form = createForm({
  onSubmit: async (values) => {
    try {
      await submitUserData(values);
    } catch (error) {
      if (error.code === 'DUPLICATE_EMAIL') {
        // Return field-specific error
        return { email: 'Email address is already registered' };
      } else if (error.code === 'SERVER_ERROR') {
        // Return form-level error
        return { [FORM_ERROR]: 'Server error occurred. Please try again later.' };
      } else {
        // Generic form-level error
        return { [FORM_ERROR]: 'An unexpected error occurred' };
      }
    }
  },
  validate: (values) => {
    const errors = {};
    
    // Field validation
    if (!values.email) {
      errors.email = 'Email is required';
    }
    
    // Business logic validation with form-level error
    if (values.age < 18 && !values.parentalConsent) {
      errors[FORM_ERROR] = 'Parental consent is required for users under 18';
    }
    
    return errors;
  }
});

// Array field error handling
const arrayForm = createForm({
  onSubmit: (values) => console.log(values),
  validate: (values) => {
    const errors = {};
    
    if (values.items && Array.isArray(values.items)) {
      // Validate individual array items
      const itemErrors = values.items.map((item, index) => {
        const itemError = {};
        if (!item.name) itemError.name = 'Name is required';
        if (!item.price || item.price <= 0) itemError.price = 'Price must be positive';
        return Object.keys(itemError).length > 0 ? itemError : undefined;
      });
      
      if (itemErrors.some(error => error)) {
        errors.items = itemErrors;
      }
      
      // Array-level validation
      if (values.items.length === 0) {
        errors.items = { [ARRAY_ERROR]: 'At least one item is required' };
      } else if (values.items.length > 10) {
        errors.items = { [ARRAY_ERROR]: 'Maximum 10 items allowed' };
      }
    }
    
    return errors;
  }
});

// Error display helper
const displayErrors = (formState) => {
  const { error, errors } = formState;
  
  // Display form-level error
  if (error) {
    showFormLevelError(error);
  }
  
  // Display field errors
  if (errors) {
    Object.keys(errors).forEach(fieldName => {
      if (fieldName === FORM_ERROR) {
        showFormLevelError(errors[fieldName]);
      } else if (Array.isArray(errors[fieldName])) {
        // Handle array field errors
        errors[fieldName].forEach((itemError, index) => {
          if (itemError) {
            Object.keys(itemError).forEach(itemFieldName => {
              if (itemFieldName === ARRAY_ERROR) {
                showArrayLevelError(fieldName, itemError[itemFieldName]);
              } else {
                showFieldError(`${fieldName}[${index}].${itemFieldName}`, itemError[itemFieldName]);
              }
            });
          }
        });
      } else if (typeof errors[fieldName] === 'object' && errors[fieldName][ARRAY_ERROR]) {
        showArrayLevelError(fieldName, errors[fieldName][ARRAY_ERROR]);
      } else {
        showFieldError(fieldName, errors[fieldName]);
      }
    });
  }
};

Subscription Item Arrays

Arrays containing all available subscription properties for form and field subscriptions.

/** Array of all available form subscription properties */
const formSubscriptionItems: readonly string[];

/** Array of all available field subscription properties */
const fieldSubscriptionItems: readonly string[];

Usage Examples:

import { formSubscriptionItems, fieldSubscriptionItems } from "final-form";

// Create subscription objects programmatically
const createFullFormSubscription = () => {
  return formSubscriptionItems.reduce((subscription, item) => {
    subscription[item] = true;
    return subscription;
  }, {});
};

const createFullFieldSubscription = () => {
  return fieldSubscriptionItems.reduce((subscription, item) => {
    subscription[item] = true;
    return subscription;
  }, {});
};

// Create selective subscriptions
const createValidationSubscription = () => {
  const validationItems = ['valid', 'invalid', 'errors', 'validating'];
  return validationItems.reduce((subscription, item) => {
    if (formSubscriptionItems.includes(item)) {
      subscription[item] = true;
    }
    return subscription;
  }, {});
};

const createSubmissionSubscription = () => {
  const submissionItems = ['submitting', 'submitSucceeded', 'submitFailed', 'submitError'];
  return submissionItems.reduce((subscription, item) => {
    if (formSubscriptionItems.includes(item)) {
      subscription[item] = true;
    }
    return subscription;
  }, {});
};

// Subscription utilities
const createConditionalSubscription = (conditions) => {
  const subscription = {};
  
  formSubscriptionItems.forEach(item => {
    if (conditions[item]) {
      subscription[item] = true;
    }
  });
  
  return subscription;
};

// Example usage
const validationOnlySubscription = createConditionalSubscription({
  valid: true,
  invalid: true,
  errors: true,
  validating: true
});

const dirtyStateSubscription = createConditionalSubscription({
  dirty: true,
  pristine: true,
  dirtySinceLastSubmit: true
});

// Field subscription utilities
const createFieldValidationSubscription = () => {
  const validationItems = ['valid', 'invalid', 'error', 'validating'];
  return validationItems.reduce((subscription, item) => {
    if (fieldSubscriptionItems.includes(item)) {
      subscription[item] = true;
    }
    return subscription;
  }, {});
};

const createFieldInteractionSubscription = () => {
  const interactionItems = ['active', 'touched', 'visited'];
  return interactionItems.reduce((subscription, item) => {
    if (fieldSubscriptionItems.includes(item)) {
      subscription[item] = true;
    }
    return subscription;
  }, {});
};

Configuration Constants

Array of valid configuration option keys for runtime validation.

/** Array of valid configuration option keys */
const configOptions: ConfigKey[];

type ConfigKey = 
  | "debug"
  | "destroyOnUnregister"
  | "initialValues"
  | "keepDirtyOnReinitialize"
  | "mutators"
  | "onSubmit"
  | "validate"
  | "validateOnBlur"
  | "callbackScheduler";

Usage Example:

import { configOptions } from "final-form";

// Validate configuration keys
const validateConfig = (config) => {
  const invalidKeys = Object.keys(config).filter(key => 
    !configOptions.includes(key)
  );
  
  if (invalidKeys.length > 0) {
    console.warn('Invalid configuration keys:', invalidKeys);
  }
  
  return invalidKeys.length === 0;
};

// Dynamic configuration
const createDynamicConfig = (options) => {
  const config = {};
  
  configOptions.forEach(key => {
    if (options[key] !== undefined) {
      config[key] = options[key];
    }
  });
  
  return config;
};

Version Information

Current version of the Final Form library.

/** Current version of Final Form */
const version: string;

Usage Example:

import { version } from "final-form";

console.log('Final Form version:', version); // "5.0.0-1"

// Version-based feature detection
const supportsNewFeatures = version >= '5.0.0';

// Debug information
const getLibraryInfo = () => ({
  library: 'final-form',
  version: version,
  timestamp: new Date().toISOString()
});