User-supplied functional options are functions that can modify your function's return value before your function returns.
- They are identity functions.
- They are passed into your function as a rest parameter.
For example:
export function makeNominalType<IN, OUT>(
contract: DataGuarantee<IN>,
input: IN,
{ onError = THROW_THE_ERROR }: OnErrorOptions = {},
...fnOpts: FunctionalOption<IN>[]
) {
// apply the contract
contract(input, { onError });
// apply any functional options we have
let retval = input;
fnOpts.forEach((fnOpt) => { retval = fnOpt(retval, { onError }); });
// all done
return (retval as unknown) as OUT;
}
// an example of how we make use of functional options
const makeContentType = (input: string, options: OnErrorOptions)
=> makeNominalType<string, ContentType>(
mustBeContentType,
input,
options,
// these are functional options
String.prototype.trim,
String.prototype.toLowerCase
);
This is a concept that we've adopted from the Golang community. See Functional options for friendly APIs to learn more.