Specialized utilities for form applications including path manipulation, unique ID generation, deprecation warnings, and safe instanceof checking. These functions provide essential infrastructure for building robust form systems.
Fast, collision-resistant unique ID generation for form elements and components.
/**
* Generate a unique identifier string
* @param len - Length of the generated ID (default: 11)
* @returns Random alphanumeric string
*/
function uid(len?: number): string;Usage Examples:
import { uid } from "@formily/shared";
// Generate default length ID (11 characters)
console.log(uid()); // "a7b9c2d4e6f"
// Generate custom length ID
console.log(uid(6)); // "x3m8k1"
console.log(uid(16)); // "p4q7r2s9t1u5v8w3"
// Form field ID generation
function createFormField(name: string, type: string) {
return {
id: `field-${uid(8)}`,
name,
type,
htmlId: `${name}-${uid(6)}` // For HTML id attribute
};
}
// Usage
const emailField = createFormField("email", "text");
// Result: { id: "field-a7b9c2d4", name: "email", type: "text", htmlId: "email-x3m8k1" }
// Component key generation for React
function generateComponentKeys(items: any[]) {
return items.map(item => ({
...item,
key: uid(12) // Unique key for React rendering
}));
}
// Session ID generation
const sessionId = `session_${uid(20)}`;
console.log(sessionId); // "session_a1b2c3d4e5f6g7h8i9j0"
// Cache key generation
function createCacheKey(prefix: string, params: Record<string, any>): string {
const paramHash = uid(8);
return `${prefix}:${paramHash}`;
}
const cacheKey = createCacheKey("user-data", { userId: 123, includeProfile: true });
console.log(cacheKey); // "user-data:m4n7p2q9"Utility for marking functions and features as deprecated with helpful messaging.
/**
* Mark a function or feature as deprecated
* @param method - Function to deprecate or deprecation message string
* @param message - Additional deprecation message
* @param help - Help text for migration
* @returns Wrapped function (if method is function) or undefined (if method is string)
*/
function deprecate<P1, P2, P3, P4, P5>(
method: any,
message?: string,
help?: string
): Function | undefined;Usage Examples:
import { deprecate } from "@formily/shared";
// Deprecate a function
const oldFunction = (x: number, y: number) => x + y;
const deprecatedAdd = deprecate(
oldFunction,
"Use the new MathUtils.add() method instead",
"See migration guide: https://example.com/migration"
);
// Using deprecated function shows warning
const result = deprecatedAdd(2, 3);
// Console warning: "oldFunction has been deprecated. Do not continue to use this api.Use the new MathUtils.add() method instead"
// Deprecate by message only
deprecate(
"OldFormComponent",
"This component will be removed in v3.0",
"Use NewFormComponent instead"
);
// Console warning: "OldFormComponent has been deprecated. Do not continue to use this api.This component will be removed in v3.0"
// Class method deprecation
class FormValidator {
// New method
validateField(value: any): boolean {
return value != null && value !== "";
}
// Deprecated method
validate = deprecate(
(value: any) => this.validateField(value),
"validate() is deprecated",
"Use validateField() instead"
);
}
const validator = new FormValidator();
validator.validate("test"); // Shows deprecation warning
// API method deprecation with migration path
class FormAPI {
// New method
submitForm(data: FormData): Promise<Response> {
return fetch("/api/form", { method: "POST", body: data });
}
// Deprecated method
submit = deprecate(
(data: any) => {
console.warn("Converting legacy data format");
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => {
formData.append(key, String(value));
});
return this.submitForm(formData);
},
"submit() method is deprecated and will be removed in v4.0",
"Use submitForm() with FormData instead. See: https://docs.example.com/form-api"
);
}Cross-environment instanceof checking that works with string class names and global objects.
/**
* Safe instanceof check that works across different JavaScript environments
* @param value - Value to check
* @param cls - Constructor function or string class name
* @returns True if value is instance of the class
*/
function instOf(value: any, cls: any): boolean;Usage Examples:
import { instOf } from "@formily/shared";
// Traditional instanceof
console.log(instOf(new Date(), Date)); // true
console.log(instOf([], Array)); // true
console.log(instOf({}, Object)); // true
// String-based class checking (useful for cross-frame scenarios)
console.log(instOf(new Date(), "Date")); // true
console.log(instOf([], "Array")); // true
console.log(instOf(/regex/, "RegExp")); // true
console.log(instOf(new Error(), "Error")); // true
// Safe checking in different environments
function safeTypeCheck(value: unknown) {
if (instOf(value, "Date")) {
// Safe to use Date methods
return value.toISOString();
} else if (instOf(value, "Array")) {
// Safe to use Array methods
return value.length;
} else if (instOf(value, "RegExp")) {
// Safe to use RegExp methods
return value.source;
}
return String(value);
}
// Cross-frame compatibility
// When objects come from different window/frame contexts, traditional instanceof fails
function handleCrossFrameObject(obj: any) {
// This works even if obj comes from a different frame
if (instOf(obj, "Array")) {
return obj.map((item: any) => processItem(item));
} else if (instOf(obj, "Date")) {
return obj.getTime();
}
return obj;
}
// Form input validation
function validateFormInput(input: unknown): boolean {
if (instOf(input, "String")) {
return input.length > 0;
} else if (instOf(input, "Number")) {
return !isNaN(input) && isFinite(input);
} else if (instOf(input, "Date")) {
return !isNaN(input.getTime());
} else if (instOf(input, "Array")) {
return input.length > 0;
}
return false;
}
// Usage
console.log(validateFormInput("hello")); // true
console.log(validateFormInput(42)); // true
console.log(validateFormInput(new Date())); // true
console.log(validateFormInput([])); // false (empty array)
console.log(validateFormInput([1, 2, 3])); // trueAdvanced path manipulation utilities re-exported from @formily/path for form field addressing.
/**
* Path manipulation class for nested object access
* Re-exported from @formily/path package
*/
class FormPath {
// Core path methods for nested object access
// Full API available in @formily/path documentation
}
/**
* Path pattern matching class
* Re-exported from @formily/path package
*/
class FormPathPattern {
// Pattern matching methods for path expressions
// Full API available in @formily/path documentation
}Usage Examples:
import { FormPath, FormPathPattern } from "@formily/shared";
// Create path for nested form field
const userPath = FormPath.parse("user.profile.email");
// Access nested data
const formData = {
user: {
profile: {
email: "user@example.com",
name: "John Doe"
}
}
};
const email = userPath.getIn(formData);
console.log(email); // "user@example.com"
// Set nested value
const newData = userPath.setIn(formData, "newemail@example.com");
console.log(newData.user.profile.email); // "newemail@example.com"
// Array path handling
const arrayPath = FormPath.parse("users.0.name");
const users = {
users: [
{ name: "Alice" },
{ name: "Bob" }
]
};
console.log(arrayPath.getIn(users)); // "Alice"
// Pattern matching for form validation
const emailPattern = FormPathPattern.parse("*.email");
const profilePattern = FormPathPattern.parse("user.profile.*");
// Check if path matches pattern
console.log(emailPattern.match("user.email")); // true
console.log(emailPattern.match("admin.email")); // true
console.log(profilePattern.match("user.profile.name")); // trueCross-platform global object reference for consistent global access.
/**
* Cross-platform global object reference
* Provides consistent access to global object across different JavaScript environments
*/
const globalThisPolyfill: Window;Usage Examples:
import { globalThisPolyfill } from "@formily/shared";
// Access global constructors safely
function createGlobalInstance(className: string, ...args: any[]) {
const Constructor = globalThisPolyfill[className];
if (typeof Constructor === "function") {
return new Constructor(...args);
}
throw new Error(`Constructor ${className} not found`);
}
// Usage
const date = createGlobalInstance("Date", "2023-01-01");
const array = createGlobalInstance("Array", 5);
// Feature detection
function hasGlobalFeature(featureName: string): boolean {
return featureName in globalThisPolyfill;
}
console.log(hasGlobalFeature("fetch")); // true in modern browsers
console.log(hasGlobalFeature("WebSocket")); // true if WebSocket available
// Polyfill registration
function registerGlobalPolyfill(name: string, implementation: any) {
if (!hasGlobalFeature(name)) {
globalThisPolyfill[name] = implementation;
}
}
// Register a polyfill if needed
registerGlobalPolyfill("requestIdleCallback", function(callback: Function) {
return setTimeout(callback, 0);
});import { uid, deprecate, instOf, FormPath } from "@formily/shared";
// Form field factory with unique IDs
class FormFieldFactory {
private static fieldCounter = 0;
static createField(type: string, name: string, config: any = {}) {
return {
id: uid(8),
instanceId: ++this.fieldCounter,
type,
name,
path: FormPath.parse(name),
htmlId: `field-${name}-${uid(6)}`,
...config
};
}
// Deprecated factory method
static create = deprecate(
this.createField,
"Use createField() instead",
"The create() method will be removed in v3.0"
);
}
// Form validation with safe type checking
class FormValidator {
validateField(field: any, value: unknown): { valid: boolean; error?: string } {
if (instOf(value, "String")) {
if (field.required && value.trim().length === 0) {
return { valid: false, error: "This field is required" };
}
if (field.minLength && value.length < field.minLength) {
return { valid: false, error: `Minimum length is ${field.minLength}` };
}
} else if (instOf(value, "Number")) {
if (field.min !== undefined && value < field.min) {
return { valid: false, error: `Minimum value is ${field.min}` };
}
if (field.max !== undefined && value > field.max) {
return { valid: false, error: `Maximum value is ${field.max}` };
}
} else if (instOf(value, "Array")) {
if (field.required && value.length === 0) {
return { valid: false, error: "Please select at least one option" };
}
}
return { valid: true };
}
}
// Usage
const fieldFactory = FormFieldFactory;
const validator = new FormValidator();
// Create form fields
const nameField = fieldFactory.createField("text", "user.name", {
required: true,
minLength: 2
});
const ageField = fieldFactory.createField("number", "user.age", {
min: 0,
max: 120
});
// Validate field values
const nameValidation = validator.validateField(nameField, "");
console.log(nameValidation); // { valid: false, error: "This field is required" }
const ageValidation = validator.validateField(ageField, 25);
console.log(ageValidation); // { valid: true }These form utilities provide the essential infrastructure needed for building sophisticated form systems with proper ID management, migration paths for deprecated features, cross-environment compatibility, and advanced path manipulation capabilities.