or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

collections.mdform-utilities.mdindex.mdobject-operations.mdreactive-patterns.mdstring-processing.mdtype-checking.mdvalidation.md
tile.json

validation.mddocs/

Validation

Utilities for checking empty values and validation with comprehensive empty detection for all data types. These functions are essential for form validation and data processing workflows.

Capabilities

Value Validation

Core validation utilities for checking value existence and validity.

/**
 * Check if value is undefined
 * @param val - Value to check
 * @returns True if value is undefined
 */
function isUndef(val: any): boolean;

/**
 * Check if value is valid (not undefined and not null)
 * @param val - Value to check
 * @returns True if value is neither undefined nor null
 */
function isValid(val: any): boolean;

Usage Examples:

import { isUndef, isValid } from "@formily/shared";

// Basic validation
console.log(isUndef(undefined)); // true
console.log(isUndef(null));      // false
console.log(isUndef(0));         // false
console.log(isUndef(""));        // false

console.log(isValid(undefined)); // false
console.log(isValid(null));      // false
console.log(isValid(0));         // true
console.log(isValid(""));        // true
console.log(isValid(false));     // true

// Form field validation
function validateFormField(value: unknown): boolean {
  if (!isValid(value)) {
    return false; // Required field is empty
  }
  // Additional validation logic...
  return true;
}

Empty Value Detection

Comprehensive empty checking that handles all JavaScript data types intelligently.

/**
 * Check if value is empty with comprehensive type-specific logic
 * @param val - Value to check for emptiness
 * @param strict - If true, uses strict emptiness checking (only null/undefined for non-collections)
 * @returns True if value is considered empty
 */
function isEmpty(val: any, strict?: boolean): boolean;

Empty Detection Rules:

  • Null/Undefined: Always empty
  • Boolean: Never empty
  • Number: Never empty (including 0)
  • String: Empty if length is 0
  • Function: Empty if length is 0 (no parameters)
  • Array: Empty if length is 0, or all elements are empty (non-strict) / null/undefined (strict)
  • Object: Empty if no enumerable properties
  • Map/Set/File: Empty if size is 0
  • Error: Empty if message is empty string

Usage Examples:

import { isEmpty } from "@formily/shared";

// Basic empty checking
console.log(isEmpty(null));           // true
console.log(isEmpty(undefined));      // true
console.log(isEmpty(""));             // true
console.log(isEmpty([]));             // true
console.log(isEmpty({}));             // true

// Non-empty values
console.log(isEmpty(0));              // false (numbers are never empty)
console.log(isEmpty(false));          // false (booleans are never empty)
console.log(isEmpty("hello"));        // false
console.log(isEmpty([1, 2, 3]));      // false
console.log(isEmpty({ a: 1 }));       // false

// Array emptiness checking
console.log(isEmpty([null, undefined, "", 0]));           // true (non-strict)
console.log(isEmpty([null, undefined, "", 0], true));     // false (strict - has 0 and "")
console.log(isEmpty([null, undefined], true));            // true (strict)

// Function emptiness
const noParams = () => "hello";
const withParams = (x: number) => x * 2;

console.log(isEmpty(noParams));       // true (no parameters)
console.log(isEmpty(withParams));     // false (has parameters)

// Collection types
console.log(isEmpty(new Map()));      // true
console.log(isEmpty(new Set()));      // true
console.log(isEmpty(new Map([["a", 1]]))); // false

// Error objects
console.log(isEmpty(new Error("")));     // true (empty message)
console.log(isEmpty(new Error("fail"))); // false (has message)

Advanced Empty Checking Examples

import { isEmpty } from "@formily/shared";

// Form validation with empty checking
function validateFormData(formData: Record<string, any>): string[] {
  const errors: string[] = [];
  
  for (const [field, value] of Object.entries(formData)) {
    if (isEmpty(value)) {
      errors.push(`${field} is required`);
    }
  }
  
  return errors;
}

// Usage
const form1 = { name: "John", email: "", age: 0 };
const errors1 = validateFormData(form1);
// Result: ["email"] (age: 0 is not empty, but email: "" is empty)

const form2 = { items: [null, undefined, ""] };
const errors2 = validateFormData(form2);
// Result: ["items"] (array with only empty values is considered empty)

// Strict vs non-strict emptiness for arrays
const mixedArray = ["hello", "", null, 0, false];

console.log(isEmpty(mixedArray));        // false (has non-empty values)
console.log(isEmpty(mixedArray, true));  // false (has non-null/undefined values)

const mostlyEmptyArray = ["", null, undefined, 0];
console.log(isEmpty(mostlyEmptyArray));        // true (all values are "empty" in non-strict mode)
console.log(isEmpty(mostlyEmptyArray, true));  // false (0 is not null/undefined)

const strictEmptyArray = [null, undefined];
console.log(isEmpty(strictEmptyArray));        // true
console.log(isEmpty(strictEmptyArray, true));  // true

Default Value Assignment

Utility for applying default values to objects with smart empty detection.

/**
 * Apply default values to target object, filling in empty properties
 * @param defaults_ - Object containing default values
 * @param targets - Object to apply defaults to
 * @returns New object with defaults applied where target values are empty
 */
function defaults(defaults_: any, targets: any): any;

Usage Examples:

import { defaults } from "@formily/shared";

// Basic defaults
const defaultConfig = { theme: "light", size: "medium", enabled: true };
const userConfig = { theme: "dark", size: null };

const finalConfig = defaults(defaultConfig, userConfig);
// Result: { theme: "dark", size: "medium", enabled: true }
// userConfig.theme overrides default, userConfig.size is null so default is used

// Nested object defaults
const defaultSettings = {
  ui: { color: "blue", font: "Arial" },
  api: { timeout: 5000, retries: 3 }
};

const userSettings = {
  ui: { color: "red" }, // font will come from defaults
  api: null             // entire api object will come from defaults
};

const settings = defaults(defaultSettings, userSettings);
/*
Result: {
  ui: { color: "red", font: "Arial" },
  api: { timeout: 5000, retries: 3 }
}
*/

// Array defaults
const defaultItems = ["apple", "banana"];
const userItems = []; // empty array

const items = defaults(defaultItems, userItems);
// Result: ["apple", "banana"] (empty array replaced with defaults)

// Form field defaults
function createFormField(fieldConfig: Partial<FormFieldConfig>): FormFieldConfig {
  const defaultFieldConfig: FormFieldConfig = {
    required: false,
    placeholder: "Enter value",
    validation: { minLength: 0, maxLength: 1000 },
    ui: { disabled: false, readonly: false }
  };

  return defaults(defaultFieldConfig, fieldConfig);
}

// Usage
const emailField = createFormField({
  required: true,
  placeholder: "Enter email",
  validation: { minLength: 5 } // maxLength will come from defaults
});

/*
Result: {
  required: true,
  placeholder: "Enter email",
  validation: { minLength: 5, maxLength: 1000 },
  ui: { disabled: false, readonly: false }
}
*/

Type Safety and Edge Cases

import { isEmpty, isValid, defaults } from "@formily/shared";

// Type-safe validation helpers
function validateRequired<T>(value: T | null | undefined): value is T {
  return isValid(value) && !isEmpty(value);
}

// Usage with type narrowing
function processUserInput(input: string | null | undefined) {
  if (validateRequired(input)) {
    // TypeScript knows input is string here
    return input.toUpperCase();
  }
  return "DEFAULT";
}

// Edge cases handled correctly
console.log(isEmpty(0));           // false (zero is not empty)
console.log(isEmpty(false));       // false (false is not empty)
console.log(isEmpty(NaN));         // false (NaN is still a number)
console.log(isEmpty("0"));         // false (string "0" is not empty)

// Special object handling
const reactElement = { $$typeof: Symbol.for("react.element"), _owner: {} };
console.log(isEmpty(reactElement)); // false (React elements are never empty)

const momentObj = { _isAMomentObject: true };
console.log(isEmpty(momentObj));    // false (Moment objects are never empty)

// Function parameter count
const arrow = () => {};             // 0 parameters
const named = function(a, b) {};    // 2 parameters
const method = (x: number, y = 10) => x + y; // 2 parameters (default still counts)

console.log(isEmpty(arrow));        // true
console.log(isEmpty(named));        // false
console.log(isEmpty(method));       // false