Home > Blockchain >  Factory returning a new function calling a target function with some default parameters
Factory returning a new function calling a target function with some default parameters

Time:09-08

How can I:

  • Create a factory function where default parameters may be provided
  • The generated function should require (required) parameters not given as default, but accept all parameters

This is my unsuccessful attempt:

interface Alpha {
  a: string;
  b: string;
}

export function alpha(params: Alpha) {
  console.log(JSON.stringify(params));
}

export function alphaDefaults(defaults: Partial<Alpha>) {
  // Not sure what Defaults should be...
  const func = (params: Defaults) => alpha({ ...defaults, ...params });
  return func;
}

const fn2 = alphaDefaults({});

// should complain about missing a and b
fn2({});

const fn3 = alphaDefaults({ a: "A" });

// should complain about missing b
fn3({ a: "NotA" });
fn3({});

const fn4 = alphaDefaults({ b: "B" });
// should complain about missing a
fn4({ b: "NotB" });
fn4({});

const fn5 = alphaDefaults({ a: "A", b: "B" });
// should not complain
fn5({ a: "NotA" });
fn5({ b: "NotB" });
fn4({ a: "Hi", b: "There" });

CodePudding user response:

Using a generic to infer and "store" what was given to the initial call, we can create the correct type based on that.

Pick all keys from Alpha that weren't given in Given, then intersect that with Partial<Alpha> to get the rest of the keys that are optional.

function alphaDefaults<Given extends Partial<Alpha>>(defaults: Given) {
  const func = (params: Pick<Alpha, Exclude<keyof Alpha, keyof Given>> & Partial<Alpha>) => alpha({ ...defaults, ...params } as Alpha);
  return func;
}

Playground

  • Related