Para aquellos que están interesados en el estilo funcional, o buscan un enfoque más expresivo para utilizar en la meta programación (como la verificación de tipos), podría ser interesante ver a Ramda biblioteca para realizar dicha tarea.
El siguiente código contiene solo funciones puras y sin puntos:
const R = require('ramda');
const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
const equalsSyncFunction = isPrototypeEquals(() => {});
const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
A partir de ES2017, las async
funciones están disponibles, por lo que también podemos verificarlas:
const equalsAsyncFunction = isPrototypeEquals(async () => {});
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
Y luego combinarlos juntos:
const isFunction = R.either(isSyncFunction, isAsyncFunction);
Por supuesto, la función debe protegerse contra null
y los undefined
valores, para que sea "segura":
const safeIsFunction = R.unless(R.isNil, isFunction);
Y, fragmento completo para resumir:
const R = require('ramda');
const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
const equalsSyncFunction = isPrototypeEquals(() => {});
const equalsAsyncFunction = isPrototypeEquals(async () => {});
const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
const isFunction = R.either(isSyncFunction, isAsyncFunction);
const safeIsFunction = R.unless(R.isNil, isFunction);
// ---
console.log(safeIsFunction( function () {} ));
console.log(safeIsFunction( () => {} ));
console.log(safeIsFunction( (async () => {}) ));
console.log(safeIsFunction( new class {} ));
console.log(safeIsFunction( {} ));
console.log(safeIsFunction( [] ));
console.log(safeIsFunction( 'a' ));
console.log(safeIsFunction( 1 ));
console.log(safeIsFunction( null ));
console.log(safeIsFunction( undefined ));
Sin embargo, tenga en cuenta que esta solución podría mostrar menos rendimiento que otras opciones disponibles debido al uso extensivo de funciones de orden superior.