Last active
June 25, 2022 13:04
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Inspired by @getify 's FPO lib and Functional Light JS Course