Skip to content

Instantly share code, notes, and snippets.

@webbower
Created June 17, 2024 23:39
Show Gist options
  • Save webbower/9a2842d150e761e8f5dde1784c4c6770 to your computer and use it in GitHub Desktop.
Save webbower/9a2842d150e761e8f5dde1784c4c6770 to your computer and use it in GitHub Desktop.
defn() Function wrapper
/**
* Define a function with an optional name
*
* Primarily useful for defining named functions with additional configuration based on method calls on the defined function since
* `const fn = (...) => {...}.fnMethod()` is invalid syntax, so you need to wrap the function definition with parens anyway.
*
* ```js
* const concat = defn('concat', (a, b) => a + b).withType([String, String], String);
* ```
*
* @param {string|Function} nameOrFnDef The function to define with no name or a value that will be stringified to the function name
* @param {Function} [fnDef] The function definition if {@link nameOrFnDef} is provided
* @returns {Function} A function with a name if both args are provided, or an anonymous function if only 1 arg is provided
* @throws {TypeError} Thrown if a function was not provided to define
*/
const defn = (nameOrFnDef, fnDef) => {
// Process the multiple possible signatures
const [name, fn] = fnDef && typeof nameOrFnDef !== 'function'
?[String(nameOrFnDef), fnDef]
: ['', nameOrFnDef];
// We need a function to define and optionally name
if (typeof fn !== 'function') {
throw new TypeError('A function was not provided to `defn()` to define');
}
// The function already has a `.name` which means it's probably already been defined
if (fn.name) {
return fn;
}
return name ? Object.defineProperty(fn, 'name', { value: name, configurable: true }) : fn;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment