JavaScript and TypeScript type checking utility functions providing precise type validation with automatic type narrowing.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Generic type checking utilities including the core type detection function, factory functions for creating custom type guards, and generic instance validation. These are the most flexible and powerful functions in the is-what library.
Returns the object type of the given payload using Object.prototype.toString. This is the foundational utility used by most other functions in the library.
/**
* Returns the object type of the given payload
* @param payload - Value to inspect
* @returns String representation of the object type
*/
function getType(payload: unknown): string;Usage Examples:
import { getType } from "is-what";
// Primitive types
getType("hello"); // "String"
getType(42); // "Number"
getType(true); // "Boolean"
getType(null); // "Null"
getType(undefined); // "Undefined"
getType(Symbol("test")); // "Symbol"
getType(123n); // "BigInt"
// Object types
getType({}); // "Object"
getType([]); // "Array"
getType(new Date()); // "Date"
getType(/regex/); // "RegExp"
getType(() => {}); // "Function"
getType(new Map()); // "Map"
getType(new Set()); // "Set"
getType(new Error()); // "Error"
// Custom classes
class MyClass {}
getType(new MyClass()); // "Object" (custom classes show as Object)
// Practical usage
function createTypeChecker(expectedType: string) {
return (value: unknown) => getType(value) === expectedType;
}
const isStringType = createTypeChecker("String");
isStringType("hello"); // true
isStringType(123); // false
// Debug utility
function debugType(value: unknown, label: string = "value") {
console.log(`${label}: ${getType(value)} = ${JSON.stringify(value)}`);
}
debugType("test", "input"); // "input: String = "test""
debugType([1, 2, 3], "array"); // "array: Array = [1,2,3]"Generic check to verify payload is of a given type. Useful for runtime type checking against constructor functions.
/**
* Does a generic check to check that the given payload is of a given type.
* In cases like Number, it will return true for NaN as NaN is a Number;
* It will, however, differentiate between object and null
* @param payload - Value to check
* @param type - Constructor function or class to check against
* @returns Type guard indicating if payload is of the specified type
* @throws {TypeError} Will throw type error if type is an invalid type
*/
function isType<T extends AnyFunction | AnyClass>(
payload: unknown,
type: T
): payload is T;
type AnyClass = new (...args: unknown[]) => unknown;Usage Examples:
import { isType } from "is-what";
// Built-in constructors
isType("hello", String); // true
isType(new String("hello"), String); // true
isType(42, Number); // true
isType(NaN, Number); // true (unlike isNumber())
isType([], Array); // true
isType(new Date(), Date); // true
// Custom classes
class MyClass {
constructor(public name: string) {}
}
class OtherClass {}
const instance = new MyClass("test");
isType(instance, MyClass); // true
isType(instance, OtherClass); // false
if (isType(value, Date)) {
// TypeScript knows value is Date
console.log(value.getFullYear());
}
// Practical usage
function validateType<T extends AnyClass>(
value: unknown,
expectedType: T,
fieldName: string
): T {
if (isType(value, expectedType)) {
return value;
}
throw new Error(
`${fieldName} must be of type ${expectedType.name}, got ${getType(value)}`
);
}
// Generic type checker factory
function createTypeChecker<T extends AnyClass>(type: T) {
return (value: unknown): value is T => {
try {
return isType(value, type);
} catch {
return false;
}
};
}
const isDateInstance = createTypeChecker(Date);
const isArrayInstance = createTypeChecker(Array);
// Error handling - function throws TypeError for invalid types
try {
isType("test", "NotAConstructor" as any); // Throws TypeError
} catch (error) {
console.log("Invalid type provided");
}Checks if a value is an instance of a class or matches a class name. Useful when you want to check for types that may not be defined in the current scope.
/**
* Checks if a value is an instance of a class or a class name.
* Useful when you want to check if a value is an instance of a class
* that may not be defined in the current scope.
* @param value - The value to recursively check
* @param classOrClassName - A class constructor or string class name
* @returns Type guard indicating if value is instance of the specified class
*/
function isInstanceOf<T extends AnyClass>(value: unknown, class_: T): value is T;
function isInstanceOf<K extends GlobalClassName>(
value: unknown,
className: K
): value is (typeof globalThis)[K];
function isInstanceOf(value: unknown, className: string): value is object;
function isInstanceOf(value: unknown, classOrClassName: AnyClass | string): boolean;Usage Examples:
import { isInstanceOf } from "is-what";
// Class constructor checking
class MyClass {
constructor(public name: string) {}
}
class ChildClass extends MyClass {
constructor(name: string, public age: number) {
super(name);
}
}
const parent = new MyClass("parent");
const child = new ChildClass("child", 25);
isInstanceOf(parent, MyClass); // true
isInstanceOf(child, MyClass); // true (inheritance)
isInstanceOf(child, ChildClass); // true
isInstanceOf(parent, ChildClass); // false
// String-based class name checking (useful for cross-context checks)
isInstanceOf(new Date(), "Date"); // true
isInstanceOf([], "Array"); // true
isInstanceOf({}, "Object"); // true
isInstanceOf(new Error(), "Error"); // true
// Browser-specific types (when available)
if (typeof OffscreenCanvas !== 'undefined') {
const canvas = new OffscreenCanvas(100, 100);
isInstanceOf(canvas, "OffscreenCanvas"); // true
}
// Practical usage - checking for types that might not exist
function handleCanvasLikeObject(obj: unknown) {
if (isInstanceOf(obj, "HTMLCanvasElement")) {
// Handle HTML canvas
return obj.getContext("2d");
}
if (isInstanceOf(obj, "OffscreenCanvas")) {
// Handle OffscreenCanvas (if available)
return obj.getContext("2d");
}
throw new Error("Expected canvas-like object");
}
// Inheritance-aware validation
function validateUserModel(obj: unknown) {
if (isInstanceOf(obj, MyClass)) {
// Works for MyClass and any subclass
return {
name: obj.name,
type: obj.constructor.name
};
}
throw new Error("Object must be instance of MyClass or its subclasses");
}
// Cross-frame/context checking (using string names)
function isArrayLike(value: unknown) {
return isInstanceOf(value, "Array") ||
(typeof value === "object" &&
value !== null &&
"length" in value);
}A factory function that creates a function to check if the payload is one of the given types. Supports 2-5 type guards with proper TypeScript union type inference.
/**
* A factory function that creates a function to check if the payload is one of the given types.
*/
function isOneOf<A, B extends A, C extends A>(
a: TypeGuard<A, B>,
b: TypeGuard<A, C>
): TypeGuard<A, B | C>;
function isOneOf<A, B extends A, C extends A, D extends A>(
a: TypeGuard<A, B>,
b: TypeGuard<A, C>,
c: TypeGuard<A, D>
): TypeGuard<A, B | C | D>;
function isOneOf<A, B extends A, C extends A, D extends A, E extends A>(
a: TypeGuard<A, B>,
b: TypeGuard<A, C>,
c: TypeGuard<A, D>,
d: TypeGuard<A, E>
): TypeGuard<A, B | C | D | E>;
function isOneOf<A, B extends A, C extends A, D extends A, E extends A, F extends A>(
a: TypeGuard<A, B>,
b: TypeGuard<A, C>,
c: TypeGuard<A, D>,
d: TypeGuard<A, E>,
e: TypeGuard<A, F>
): TypeGuard<A, B | C | D | E | F>;
type TypeGuard<A, B extends A> = (payload: A) => payload is B;Usage Examples:
import { isOneOf, isNull, isUndefined, isString, isNumber } from "is-what";
// Create composite type checkers
const isNullOrUndefined = isOneOf(isNull, isUndefined);
const isStringOrNumber = isOneOf(isString, isNumber);
// Usage
isNullOrUndefined(null); // true
isNullOrUndefined(undefined); // true
isNullOrUndefined("hello"); // false
isStringOrNumber("hello"); // true
isStringOrNumber(42); // true
isStringOrNumber(true); // false
// TypeScript type narrowing works correctly
function processValue(value: unknown) {
if (isNullOrUndefined(value)) {
// TypeScript knows value is null | undefined
console.log("No value provided");
return null;
}
if (isStringOrNumber(value)) {
// TypeScript knows value is string | number
return value.toString(); // Both types have toString()
}
return "Other type";
}
// Complex combinations
const isPrimitiveOrNull = isOneOf(
isString,
isNumber,
isNull
);
// Custom type guards with isOneOf
function isEven(value: unknown): value is number {
return isNumber(value) && value % 2 === 0;
}
function isOdd(value: unknown): value is number {
return isNumber(value) && value % 2 === 1;
}
const isEvenOrOdd = isOneOf(isEven, isOdd);
// Practical usage - form validation
const isValidId = isOneOf(isString, isNumber);
function validateUserId(id: unknown) {
if (isValidId(id)) {
// TypeScript knows id is string | number
return { valid: true, id: id.toString() };
}
return { valid: false, error: "ID must be string or number" };
}
// API response validation
import { isArray, isObject } from "is-what";
const isArrayOrObject = isOneOf(isArray, isPlainObject);
function processApiResponse(response: unknown) {
if (isArrayOrObject(response)) {
// TypeScript knows response is unknown[] | PlainObject
return JSON.stringify(response, null, 2);
}
throw new Error("API response must be array or object");
}
// Error handling combinations
import { isError } from "is-what";
const isErrorOrString = isOneOf(isError, isString);
function handleResult(result: unknown) {
if (isErrorOrString(result)) {
// TypeScript knows result is Error | string
const message = isError(result) ? result.message : result;
console.log("Error:", message);
return null;
}
return result; // Success case
}import {
getType,
isType,
isInstanceOf,
isOneOf,
isString,
isNumber,
isFunction
} from "is-what";
// Advanced type analysis
function analyzeTypeComprehensively(value: unknown) {
const basicType = getType(value);
const analysis = { basicType, details: {} as any };
// Check against common constructors
const constructors = [String, Number, Boolean, Array, Object, Date, RegExp];
for (const ctor of constructors) {
try {
if (isType(value, ctor)) {
analysis.details[ctor.name] = true;
}
} catch {
// Skip invalid constructors
}
}
// Check inheritance patterns
if (value && typeof value === "object") {
analysis.details.constructor = value.constructor?.name || "Unknown";
analysis.details.hasPrototype = Object.getPrototypeOf(value) !== null;
}
return analysis;
}
// Generic validation system
class TypeValidator {
private validators = new Map<string, (value: unknown) => boolean>();
register(name: string, validator: (value: unknown) => boolean) {
this.validators.set(name, validator);
}
validate(value: unknown, typeName: string) {
const validator = this.validators.get(typeName);
if (!validator) {
throw new Error(`Unknown type validator: ${typeName}`);
}
return validator(value);
}
createCompositeValidator(...typeNames: string[]) {
const validators = typeNames.map(name => this.validators.get(name))
.filter(Boolean);
return (value: unknown) => validators.some(validator => validator!(value));
}
}
// Usage
const validator = new TypeValidator();
validator.register("string", isString);
validator.register("number", isNumber);
validator.register("function", isFunction);
const isStringOrNumber = validator.createCompositeValidator("string", "number");
// Type-safe object creation
function createTypedObject<T extends AnyClass>(
type: T,
...args: ConstructorParameters<T>
): InstanceType<T> {
const instance = new type(...args);
if (isInstanceOf(instance, type)) {
return instance as InstanceType<T>;
}
throw new Error(`Failed to create instance of ${type.name}`);
}
// Example usage
const analysis = analyzeTypeComprehensively(new Date());
// Returns: {
// basicType: "Date",
// details: {
// Date: true,
// Object: true,
// constructor: "Date",
// hasPrototype: true
// }
// }
class User {
constructor(public name: string, public age: number) {}
}
const user = createTypedObject(User, "Alice", 30);
// TypeScript knows user is User instance
console.log(user.name); // "Alice"type AnyClass = new (...args: unknown[]) => unknown;
type TypeGuard<A, B extends A> = (payload: A) => payload is B;
type GlobalClassName = {
[K in keyof typeof globalThis]: (typeof globalThis)[K] extends AnyClass ? K : never;
}[keyof typeof globalThis];