Generics types for an builder function

You can resolve the issue by using some helper type which constructs template for option data based on L – label field name and V – value field name:

type OptionTemplate<L extends string, V extends string, LV = string, VV = string | number> = {
  [key in L]: LV;
} & {
  [key in V]: VV;
}

After you need to change the signature of your optionValues function:

function optionValues<L extends string, V extends string, T extends OptionTemplate<L, V>>(entities: T[], label: L, value: V) {
  return entities.map((e, index) => {
    return <option key={index} value={e[value]}>{ e[label] }</option>
  })
}

And finally here is the full code:

type OptionTemplate<L extends string, V extends string, LV = string, VV = string | number> = {
  [key in L]: LV;
} & {
  [key in V]: VV;
}

function optionValues<L extends string, V extends string, T extends OptionTemplate<L, V>>(entities: T[], label: L, value: V) {
  return entities.map((e, index) => {
    return <option key={index} value={e[value]}>{ e[label] }</option>
  })
}

const users = [
  { id: 1, name: "Foo"},
  { id: 2, name: "Bar"},
  { id: 3, name: "Baz"}
]

optionValues(users, "name", "id");

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top