Home > Software design >  How to create type/interface from another type interface?
How to create type/interface from another type interface?

Time:05-06

I have interface of values types:

interface ValuesTypes {
  foo: string;
  bar: number;
}

and Union of Controls:

type Controls = 'selectFoo' | 'tbxBar';

and map controls to values names:

const mapControlsToValues: Record<Controls, keyof ValuesTypes> = {
  selectFoo: 'foo',
  tbxBar: 'bar',
};

How can I get the ElementsTypes interface using code described above?

interface ElementsTypes {
  selectFoo: string;
  tbxBar: number;
}

CodePudding user response:

The way you defined mapControlsToValues doesn't really work, because you are defining each value as a keyof ValuesTypes, meaning, that each value can actually be foo or bar, and not the type that you passed in.

So, my advice is that you should rely on TypeScript's inference to do the job! In order to do that, you must create a generic function and use the "literal" type that you passed in. This way you will still have the same type safety, and be able to have concrete typing for your mapControlsToValues object.

1- Create a generic function

function getControlValues<T extends Record<Controls, keyof ValuesTypes>>(arg: T){
  return arg;
}

2- Extract the type of the generated type

const mapControlsToValues = getControlValues({
  selectFoo: 'foo',
  tbxBar: 'bar',
})

type ControlValuesType = typeof mapControlsToValues;

3- Create a new object type based on your ControlValuesType

type ElementsTypes = {
  [Key in keyof ControlValuesType]: ValuesTypes[ControlValuesType[Key]];
};

And that's it, you have defined a type that follows the ElementsTypes interface. If you really need it to be an interface you can always extend the created type like so:

interface MyInterface extends ElementsTypes {}

TS Playground

  • Related