Function Guards
Collection of type-safe utility functions for runtime type checking of functions. These guards enable TypeScript type narrowing and runtime validation.
Import
import { isFunction, isMethodDescriptor, isPromise, isReturningPromise } from 'nhb-toolbox';
Type Definitions
/** Generic function type */
export type GenericFn = (...args: unknown[]) => unknown;
/** Asynchronous function type */
export type AsyncFunction<T> = (...args: unknown[]) => Promise<T>;
isFunction
function isFunction(value: unknown): value is GenericFn
Description
Determines if a value is a callable function. Works for all function types including async functions, generators, and class constructors.
Examples
// Function checks
isFunction(function() {}); // true
isFunction(() => {}); // true
isFunction(class {}); // true
isFunction(async function() {}); // true
isFunction(function*() {}); // true
// Non-functions
isFunction({}); // false
isFunction(null); // false
isFunction('function'); // false
// Type narrowing
const callback: unknown = () => console.log('called');
if (isFunction(callback)) {
callback(); // safely callable
}
// Constructor check
function createInstance(ctor: unknown, ...args: unknown[]) {
if (isFunction(ctor)) {
return new ctor(...args);
}
throw new Error('Constructor expected');
}
Notes
- Returns true for all callable values
- Includes async functions and generators
- Properly handles edge cases like bound functions
isMethodDescriptor
function isMethodDescriptor(descriptor: PropertyDescriptor | undefined): boolean
Description
Specialized guard checking if a property descriptor represents a method (function-valued property). Useful for reflection and decorators.
Examples
const obj = {
method() {},
prop: 'value',
get accessor() { return this.prop; }
};
// Checking descriptors
const methodDesc = Object.getOwnPropertyDescriptor(obj, 'method');
isMethodDescriptor(methodDesc); // true
const propDesc = Object.getOwnPropertyDescriptor(obj, 'prop');
isMethodDescriptor(propDesc); // false
const accessorDesc = Object.getOwnPropertyDescriptor(obj, 'accessor');
isMethodDescriptor(accessorDesc); // false
// Practical usage in decorators
function logMethod(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
if (!isMethodDescriptor(descriptor)) {
throw new Error('@logMethod can only decorate methods');
}
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with`, args);
return original.apply(this, args);
};
}
Use Cases
- Property descriptor validation
- Decorator implementations
- Reflection-based code
- Runtime method checking
isPromise
function isPromise(value: unknown): value is Promise<unknown>
Description
Determines if a value is a Promise (thenable object). Works with native Promises and most Promise implementations.
Examples
// Promise detection
isPromise(Promise.resolve()); // true
isPromise(new Promise(() => {})); // true
isPromise({
then: () => {},
catch: () => {}
}); // true (thenable)
// Non-promises
isPromise({}); // false
isPromise({ then: 1 }); // false (non-function then)
isPromise(null); // false
// Async handling
async function process(value: unknown) {
if (isPromise(value)) {
value = await value;
}
// ... process value
}
Notes
- Detects both native Promises and thenables
- Works across different Promise implementations
- Useful for promise unwrapping utilities
isReturningPromise
function isReturningPromise<T>(fn: unknown): fn is AsyncFunction<T>
Description
Checks if a function returns a Promise. Identifies async functions and regular functions that return promises.
Examples
// Async functions
isReturningPromise(async () => {}); // true
isReturningPromise(async function() {}); // true
// Promise-returning functions
isReturningPromise(() => Promise.resolve()); // true
isReturningPromise(() => new Promise(() => {})); // true
// Non-async functions
isReturningPromise(() => {}); // false
isReturningPromise(function*() {}); // false
// Type-safe handling
function wrapAsync(fn: unknown) {
if (!isReturningPromise(fn)) {
throw new Error('Function must return a Promise');
}
return async (...args: unknown[]) => {
try {
return await fn(...args);
} catch (error) {
console.error('Async error:', error);
throw error;
}
};
}
Notes
- Detects both async functions and explicit Promise returns
- Works with bound functions and methods
- Useful for API boundary validation
Aliases
Main Export | Alias Names |
---|---|
isMethodDescriptor | isMethod |
isReturningPromise | doesReturnPromise |