Skip to content

Instantly share code, notes, and snippets.

@OlaoluwaM
Last active June 25, 2022 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OlaoluwaM/d61c00bd37c08f0cdb70cc3e3c2947d1 to your computer and use it in GitHub Desktop.
Save OlaoluwaM/d61c00bd37c08f0cdb70cc3e3c2947d1 to your computer and use it in GitHub Desktop.
A way of invoking your functions with a named parameter technique as opposed to positional parameters. Really useful in functional programming where there is a great emphasis on the manipulation of function shapes
// test #1
const exampleFn = (a: number, b:string, c: boolean) => [a, b, c]
const namedParamExampleFn = toNamedParams(exampleFn)
console.log(namedParamExampleFn({c: true, a: 1}))
// test #2
function testFn(a: number, b: string) {
return a + b
}
const namedTestFn = toNamedParams(testFn)
console.log(namedTestFn({b: 's', a: 1}))
type AnyFunction<P = any, RT = unknown> = (...args: P[]) => RT
type FuncParams = string[]
function toNamedParams<Fn extends AnyFunction>(fn: Fn) {
const initialFuncParamObj = generateInitialParamsObj(getFuncPositionalParams(fn))
return (passedArgsObj: Record<string, Parameters<Fn>[number]) => {
const funcArgsArr = Object.values({...initialFuncParamObj, ...passedArgsObj})
return fn.apply(null, funcArgsArr)
}
}
function getFuncPositionalParams(fn: AnyFunction) {
const REGEX_FOR = {
CONTENT_WITHIN_PARENTHESES: /\([^)]*\)/m,
PARENTHESES: /\(|\)/g,
SPACE_AND_COMMA_DELIMITED_LIST: /\s*,\s*/
}
const funcParamsStrMatchArr = fn.toString().match(REGEX_FOR.CONTENT_WITHIN_PARENTHESES)
if (!funcParamsStrMatchArr) throw new Error(`Could not extract args for ${fn.name} function`)
const [funcParamsStr] = funcParamsStrMatchArr
const funcParamsStrWithoutBraces = funcParamsStr.replace(REGEX_FOR.PARENTHESES, '')
const funcParamsArr = funcParamsStrWithoutBraces.split(REGEX_FOR.SPACE_AND_COMMA_DELIMITED_LIST).map(removeEverythingAfterFirstSpace)
return funcParamsArr
}
function removeEverythingAfterFirstSpace(str: string): string {
const SPACE_CHAR = ' '
const indexOfFirstSpaceCharInStr = str.indexOf(SPACE_CHAR)
if (indexOfFirstSpaceCharInStr === -1) return str
const truncatedStr = str.slice(0, indexOfFirstSpaceCharInStr)
return truncatedStr
}
function generateInitialParamsObj(functionParams: FuncParams) {
const funcParamsObj = functionParams.reduce(generateEmptyParamObj, {})
return funcParamsObj
}
function generateEmptyParamObj(obj: Record<string, undefined>, param: string): Record<string, undefined> {
return {...obj, [param]: undefined}
}
@OlaoluwaM
Copy link
Author

Inspired by @getify 's FPO lib and Functional Light JS Course

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment