Comprehensive type checking utilities with full TypeScript type guard support for runtime type safety. These functions provide both runtime type checking and compile-time type narrowing in TypeScript.
Core type checking functions with TypeScript type guards.
/**
* Get the internal [[Class]] property of an object
* @param obj - Object to get type of
* @returns Type string in format "[object Type]"
*/
function getType(obj: any): string;
/**
* Check if value is a function
* @param val - Value to check
* @returns True if value is a function
*/
function isFn(val: any): val is Function;
/**
* Check if value is an array (alias for Array.isArray)
* @param val - Value to check
* @returns True if value is an array
*/
function isArr(val: any): val is any[];
/**
* Check if value is a plain object (created by {} or new Object())
* @param val - Value to check
* @returns True if value is a plain object
*/
function isPlainObj(val: any): val is object;
/**
* Check if value is a string
* @param val - Value to check
* @returns True if value is a string
*/
function isStr(val: any): val is string;
/**
* Check if value is a boolean
* @param val - Value to check
* @returns True if value is a boolean
*/
function isBool(val: any): val is boolean;
/**
* Check if value is a number
* @param val - Value to check
* @returns True if value is a number
*/
function isNum(val: any): val is number;
/**
* Check if value is any object type
* @param val - Value to check
* @returns True if typeof value === 'object'
*/
function isObj(val: unknown): val is object;
/**
* Check if value is a RegExp
* @param val - Value to check
* @returns True if value is a regular expression
*/
function isRegExp(val: any): val is RegExp;Usage Examples:
import {
getType, isFn, isArr, isPlainObj, isStr, isBool,
isNum, isObj, isRegExp
} from "@formily/shared";
// Basic type checking with type guards
function processValue(value: unknown) {
if (isStr(value)) {
// TypeScript knows value is string here
console.log(value.toUpperCase());
} else if (isNum(value)) {
// TypeScript knows value is number here
console.log(value.toFixed(2));
} else if (isArr(value)) {
// TypeScript knows value is array here
console.log(value.length);
}
}
// Get detailed type information
console.log(getType([])); // "[object Array]"
console.log(getType({})); // "[object Object]"
console.log(getType(new Date())); // "[object Date]"
// Function type checking
const callback = (x: number) => x * 2;
if (isFn(callback)) {
const result = callback(5); // Safe to call
}
// Plain object vs other objects
console.log(isPlainObj({})); // true
console.log(isPlainObj(new Date())); // false
console.log(isPlainObj([])); // falseSpecialized checking for collection types.
/**
* Check if value is a Map
* @param val - Value to check
* @returns True if value is a Map instance
*/
function isMap(val: any): val is Map<any, any>;
/**
* Check if value is a Set
* @param val - Value to check
* @returns True if value is a Set instance
*/
function isSet(val: any): val is Set<any>;
/**
* Check if value is a WeakMap
* @param val - Value to check
* @returns True if value is a WeakMap instance
*/
function isWeakMap(val: any): val is WeakMap<any, any>;
/**
* Check if value is a WeakSet
* @param val - Value to check
* @returns True if value is a WeakSet instance
*/
function isWeakSet(val: any): val is WeakSet<any>;Usage Examples:
import { isMap, isSet, isWeakMap, isWeakSet } from "@formily/shared";
// Working with different collection types
function processCollection(collection: unknown) {
if (isMap(collection)) {
// TypeScript knows it's Map<any, any>
console.log(`Map with ${collection.size} entries`);
collection.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
} else if (isSet(collection)) {
// TypeScript knows it's Set<any>
console.log(`Set with ${collection.size} items`);
collection.forEach(value => console.log(value));
}
}
// Example usage
const myMap = new Map([["a", 1], ["b", 2]]);
const mySet = new Set([1, 2, 3]);
processCollection(myMap); // Processes as Map
processCollection(mySet); // Processes as SetEnhanced numeric type checking including number-like strings.
/**
* Check if value is number-like (number or numeric string)
* @param index - Value to check
* @returns True if value is number or matches /^\d+$/
*/
function isNumberLike(index: any): index is number;Usage Examples:
import { isNumberLike, isNum } from "@formily/shared";
// Number-like checking for array indices and similar
console.log(isNumberLike(42)); // true
console.log(isNumberLike("42")); // true
console.log(isNumberLike("abc")); // false
console.log(isNumberLike("12.3")); // false (only integers)
// Useful for array index validation
function safeArrayAccess<T>(arr: T[], index: unknown): T | undefined {
if (isNumberLike(index)) {
return arr[Number(index)];
}
return undefined;
}
const items = ["a", "b", "c"];
console.log(safeArrayAccess(items, "1")); // "b"
console.log(safeArrayAccess(items, "x")); // undefinedSpecialized checking for React and HTML elements.
/**
* Check if value is a React element
* @param obj - Value to check
* @returns True if value has React element properties
*/
function isReactElement(obj: any): boolean;
/**
* Check if value is an HTML element
* @param target - Value to check
* @returns True if value is an HTML element
*/
function isHTMLElement(target: any): target is EventTarget;Usage Examples:
import { isReactElement, isHTMLElement } from "@formily/shared";
// React element detection
import React from "react";
const element = React.createElement("div", {}, "Hello");
const notElement = { type: "div" };
console.log(isReactElement(element)); // true
console.log(isReactElement(notElement)); // false
// HTML element detection
function handleElement(target: unknown) {
if (isHTMLElement(target)) {
// TypeScript knows target is EventTarget
target.addEventListener("click", () => {
console.log("Clicked!");
});
}
}
// Usage with DOM elements
const button = document.createElement("button");
handleElement(button); // Adds event listener
// Won't work with non-HTML elements
handleElement("not an element"); // No event listener added// These interfaces are used by other modules but defined here
type Subscriber<S> = (payload: S) => void;
interface Subscription<S> {
notify?: (payload: S) => void | boolean;
filter?: (payload: S) => any;
}import {
isFn, isStr, isNum, isArr, isPlainObj,
isMap, isSet, isReactElement
} from "@formily/shared";
// Type-safe data processing
function processData(data: unknown): ProcessedData {
if (isPlainObj(data)) {
// Handle object data
const result: Record<string, any> = {};
for (const [key, value] of Object.entries(data)) {
if (isStr(value)) {
result[key] = value.trim();
} else if (isNum(value)) {
result[key] = Math.round(value);
} else if (isArr(value)) {
result[key] = value.filter(item => item != null);
}
}
return result;
} else if (isArr(data)) {
// Handle array data
return data.map(item => processData(item));
} else {
// Handle primitive data
return data;
}
}
// Runtime type validation for API responses
function validateUserData(userData: unknown): userData is UserData {
return (
isPlainObj(userData) &&
isStr(userData.name) &&
isNum(userData.age) &&
isStr(userData.email)
);
}
// Type-safe form field processing
function processFormField(field: unknown) {
if (isReactElement(field)) {
// Handle React component field
return cloneElement(field, { validated: true });
} else if (isFn(field)) {
// Handle render function field
return field({ validated: true });
} else if (isStr(field)) {
// Handle string field
return field.trim();
}
return field;
}