Skip to content

isFunction

检查值是否为函数类型。

基础用法

typescript
import { isFunction } from 'radash'

console.log(isFunction(() => {}))           // true
console.log(isFunction(function() {}))      // true
console.log(isFunction(async () => {}))     // true
console.log(isFunction('hello'))            // false
console.log(isFunction(123))                // false
console.log(isFunction({}))                 // false

语法

typescript
function isFunction(value: any): value is Function

参数

  • value (any): 要检查的值

返回值

返回一个布尔值,如果值是函数则返回 true,否则返回 false。同时作为TypeScript类型守卫。

示例

基本类型检查

typescript
import { isFunction } from 'radash'

// 函数类型
console.log(isFunction(() => {}))           // true
console.log(isFunction(function() {}))      // true
console.log(isFunction(async () => {}))     // true
console.log(isFunction(function*() {}))     // true
console.log(isFunction(() => 'hello'))      // true

// 非函数类型
console.log(isFunction('hello'))            // false
console.log(isFunction(123))                // false
console.log(isFunction(true))               // false
console.log(isFunction(null))               // false
console.log(isFunction(undefined))          // false
console.log(isFunction([]))                 // false
console.log(isFunction({}))                 // false

不同类型函数检查

typescript
import { isFunction } from 'radash'

// 箭头函数
const arrowFunc = () => 'hello'
console.log(isFunction(arrowFunc))          // true

// 普通函数
function normalFunc() { return 'hello' }
console.log(isFunction(normalFunc))         // true

// 异步函数
async function asyncFunc() { return 'hello' }
console.log(isFunction(asyncFunc))          // true

// 生成器函数
function* generatorFunc() { yield 'hello' }
console.log(isFunction(generatorFunc))      // true

// 构造函数
function Constructor() { this.name = 'test' }
console.log(isFunction(Constructor))        // true

// 类构造函数
class MyClass {}
console.log(isFunction(MyClass))            // true

类型守卫使用

typescript
import { isFunction } from 'radash'

function processValue(value: unknown) {
  if (isFunction(value)) {
    // TypeScript 知道 value 是函数
    console.log('Processing function:', value.name || 'anonymous')
    return value()
  }
  
  console.log('Not a function')
  return null
}

console.log(processValue(() => 'hello'))    // Processing function: anonymous hello
console.log(processValue('not a function')) // Not a function null

数组过滤

typescript
import { isFunction } from 'radash'

const mixedArray = [
  () => 'hello',
  'string',
  123,
  function() { return 'world' },
  async () => 'async',
  {},
  []
]

const functions = mixedArray.filter(isFunction)
console.log(functions.length) // 3

const nonFunctions = mixedArray.filter(item => !isFunction(item))
console.log(nonFunctions.length) // 4

对象属性检查

typescript
import { isFunction } from 'radash'

const obj = {
  name: 'Alice',
  age: 25,
  greet: () => 'Hello!',
  calculate: function(a: number, b: number) { return a + b },
  async fetchData() { return 'data' },
  isActive: true
}

const functionProperties = Object.entries(obj)
  .filter(([key, value]) => isFunction(value))
  .map(([key, value]) => ({ key, type: value.constructor.name }))

console.log(functionProperties)
// [
//   { key: 'greet', type: 'Function' },
//   { key: 'calculate', type: 'Function' },
//   { key: 'fetchData', type: 'AsyncFunction' }
// ]

事件处理器检查

typescript
import { isFunction } from 'radash'

const eventHandlers = {
  onClick: () => console.log('clicked'),
  onSubmit: function(data: any) { console.log('submitted', data) },
  onError: null,
  onLoad: undefined,
  onResize: 'not a function'
}

const validHandlers = Object.entries(eventHandlers)
  .filter(([key, value]) => isFunction(value))
  .reduce((acc, [key, value]) => {
    acc[key] = value
    return acc
  }, {} as Record<string, Function>)

console.log(Object.keys(validHandlers)) // ['onClick', 'onSubmit']

API响应处理

typescript
import { isFunction } from 'radash'

interface ApiResponse {
  data: unknown
  handlers: Record<string, unknown>
  callbacks: unknown[]
}

function processApiResponse(response: ApiResponse) {
  const validHandlers = Object.entries(response.handlers)
    .filter(([key, value]) => isFunction(value))
    .reduce((acc, [key, value]) => {
      acc[key] = value as Function
      return acc
    }, {} as Record<string, Function>)

  const validCallbacks = response.callbacks.filter(isFunction)

  return {
    data: response.data,
    validHandlers,
    validCallbacks
  }
}

const response: ApiResponse = {
  data: { id: 1, name: 'Alice' },
  handlers: {
    success: (data: any) => console.log('Success:', data),
    error: 'not a function',
    complete: () => console.log('Complete')
  },
  callbacks: [
    () => 'callback1',
    'not a function',
    () => 'callback2'
  ]
}

const processed = processApiResponse(response)
console.log(Object.keys(processed.validHandlers)) // ['success', 'complete']
console.log(processed.validCallbacks.length) // 2

插件系统

typescript
import { isFunction } from 'radash'

interface Plugin {
  name: string
  init?: Function
  destroy?: Function
  render?: Function
}

function validatePlugin(plugin: unknown): plugin is Plugin {
  if (typeof plugin !== 'object' || plugin === null) return false
  
  const p = plugin as any
  
  if (typeof p.name !== 'string') return false
  
  if (p.init !== undefined && !isFunction(p.init)) return false
  if (p.destroy !== undefined && !isFunction(p.destroy)) return false
  if (p.render !== undefined && !isFunction(p.render)) return false
  
  return true
}

const validPlugin: Plugin = {
  name: 'MyPlugin',
  init: () => console.log('Plugin initialized'),
  render: () => '<div>Plugin content</div>'
}

const invalidPlugin = {
  name: 'InvalidPlugin',
  init: 'not a function'
}

console.log(validatePlugin(validPlugin))   // true
console.log(validatePlugin(invalidPlugin)) // false

中间件系统

typescript
import { isFunction } from 'radash'

type Middleware = (req: any, res: any, next: Function) => void

function validateMiddleware(middleware: unknown): middleware is Middleware {
  return isFunction(middleware) && middleware.length >= 2
}

const validMiddleware: Middleware = (req, res, next) => {
  console.log('Processing request')
  next()
}

const invalidMiddleware = 'not a function'

const middlewareArray = [
  validMiddleware,
  invalidMiddleware,
  (req: any, res: any) => console.log('No next parameter'),
  (req: any) => console.log('Missing parameters')
]

const validMiddlewares = middlewareArray.filter(validateMiddleware)
console.log(validMiddlewares.length) // 1

配置验证

typescript
import { isFunction } from 'radash'

interface Config {
  port: number
  host: string
  handlers: Record<string, unknown>
  validators: unknown[]
}

function validateConfig(config: Config) {
  const errors: string[] = []
  
  // 验证处理器
  Object.entries(config.handlers).forEach(([key, value]) => {
    if (!isFunction(value)) {
      errors.push(`Handler '${key}' must be a function`)
    }
  })
  
  // 验证验证器
  config.validators.forEach((validator, index) => {
    if (!isFunction(validator)) {
      errors.push(`Validator at index ${index} must be a function`)
    }
  })
  
  return errors
}

const config: Config = {
  port: 3000,
  host: 'localhost',
  handlers: {
    onRequest: (req: any) => console.log(req),
    onResponse: 'not a function',
    onError: () => console.log('Error')
  },
  validators: [
    (data: any) => data.id > 0,
    'not a function',
    (data: any) => data.name.length > 0
  ]
}

console.log(validateConfig(config))
// ['Handler \'onResponse\' must be a function', 'Validator at index 1 must be a function']

回调函数处理

typescript
import { isFunction } from 'radash'

function executeCallback(callback: unknown, ...args: any[]) {
  if (!isFunction(callback)) {
    console.warn('Callback is not a function')
    return
  }
  
  try {
    return callback(...args)
  } catch (error) {
    console.error('Callback execution failed:', error)
  }
}

// 有效回调
executeCallback((name: string) => `Hello ${name}!`, 'Alice')
// 输出: Hello Alice!

// 无效回调
executeCallback('not a function', 'Alice')
// 输出: Callback is not a function

事件系统

typescript
import { isFunction } from 'radash'

class EventEmitter {
  private events: Record<string, Function[]> = {}
  
  on(event: string, listener: unknown) {
    if (!isFunction(listener)) {
      throw new Error('Listener must be a function')
    }
    
    if (!this.events[event]) {
      this.events[event] = []
    }
    
    this.events[event].push(listener as Function)
  }
  
  emit(event: string, ...args: any[]) {
    const listeners = this.events[event] || []
    listeners.forEach(listener => {
      if (isFunction(listener)) {
        listener(...args)
      }
    })
  }
}

const emitter = new EventEmitter()

// 添加有效监听器
emitter.on('message', (data: any) => console.log('Received:', data))

// 尝试添加无效监听器
try {
  emitter.on('error', 'not a function')
} catch (error) {
  console.log('Error caught:', error.message) // Listener must be a function
}

emitter.emit('message', 'Hello World') // Received: Hello World

工具函数检查

typescript
import { isFunction } from 'radash'

const utils = {
  format: (value: any) => value.toString(),
  validate: (value: any) => value !== null,
  transform: 'not a function',
  process: null
}

const functionUtils = Object.entries(utils)
  .filter(([key, value]) => isFunction(value))
  .reduce((acc, [key, value]) => {
    acc[key] = value as Function
    return acc
  }, {} as Record<string, Function>)

console.log(Object.keys(functionUtils)) // ['format', 'validate']

异步函数检查

typescript
import { isFunction } from 'radash'

const asyncFunctions = {
  fetchData: async () => 'data',
  processData: async (data: any) => data.toUpperCase(),
  syncFunction: () => 'sync',
  notFunction: 'string'
}

const validAsyncFunctions = Object.entries(asyncFunctions)
  .filter(([key, value]) => isFunction(value))
  .map(([key, value]) => ({
    name: key,
    isAsync: value.constructor.name === 'AsyncFunction'
  }))

console.log(validAsyncFunctions)
// [
//   { name: 'fetchData', isAsync: true },
//   { name: 'processData', isAsync: true },
//   { name: 'syncFunction', isAsync: false }
// ]

函数参数检查

typescript
import { isFunction } from 'radash'

function analyzeFunction(func: unknown) {
  if (!isFunction(func)) {
    return { isValid: false, reason: 'Not a function' }
  }
  
  const f = func as Function
  return {
    isValid: true,
    name: f.name || 'anonymous',
    length: f.length,
    isAsync: f.constructor.name === 'AsyncFunction',
    isGenerator: f.constructor.name === 'GeneratorFunction'
  }
}

console.log(analyzeFunction(() => {}))
// { isValid: true, name: 'anonymous', length: 0, isAsync: false, isGenerator: false }

console.log(analyzeFunction(async (a: number, b: number) => a + b))
// { isValid: true, name: 'anonymous', length: 2, isAsync: true, isGenerator: false }

console.log(analyzeFunction('not a function'))
// { isValid: false, reason: 'Not a function' }

函数组合

typescript
import { isFunction } from 'radash'

function compose(...functions: unknown[]) {
  const validFunctions = functions.filter(isFunction) as Function[]
  
  if (validFunctions.length === 0) {
    return (x: any) => x
  }
  
  return (x: any) => validFunctions.reduceRight((acc, fn) => fn(acc), x)
}

const addOne = (x: number) => x + 1
const double = (x: number) => x * 2
const square = (x: number) => x * x

const composed = compose(square, double, addOne, 'not a function')
console.log(composed(5)) // 144 (5 + 1 = 6, 6 * 2 = 12, 12 * 12 = 144)

注意事项

  1. 函数类型: 检查所有类型的函数(普通函数、箭头函数、异步函数、生成器函数)
  2. 构造函数: 构造函数也被认为是函数
  3. : 类本身是函数(构造函数)
  4. 类型守卫: 作为TypeScript类型守卫使用
  5. 性能: 检查速度很快,适合高频使用

与其他方法的区别

  • isFunction(): 检查是否为函数
  • typeof value === 'function': 原生JavaScript检查
  • value instanceof Function: 检查是否为Function实例
  • value.constructor === Function: 检查构造函数

实际应用场景

  1. 事件处理: 验证事件监听器
  2. 回调函数: 验证回调参数
  3. 插件系统: 验证插件方法
  4. 中间件: 验证中间件函数
  5. API设计: 验证API回调
  6. 工具函数: 验证工具函数参数

Released under the MIT License.