'Unique typescript generic types for each entry in an object

I'm having trouble typing something like the following object.

The value for fn for both image and line are the type definition for brevity instead of including an actual function. I understand in JS these would be functions with that type.

const obj = {
  image: {
    fn: (config: ImageConfig) => ImageProps,
    Component: (props: ImageProps) => ImageElement
  },
  line: {
    fn: (config: ImageConfig) => LineProps,
    Component: (props: LineProps) => LineElement
  },

  // ...

}

How would I go about typing this in TS? I want to treat the top level keys (image and line) as arbitrary (these keys could be any value). But I want their values to always contain a key of fn and a key of Component with a relationship between the arguments and return value for fn and Component. Namely that the two compose together.

I have the following type which is easy to understand with the above:

type Element<Props, Config> = { 
  fn: (x: Config) => Props; 
  Component: (props: Props) => JSX.Element 
};

But I can't create a type that uses Element to allow for distinct generics for each entry in the object.

I can't do

type MyConfig<Props, Config> = {
  [key: string]: Element<Props, Config>
};

since I want each instance of Props and Config for each entry in the object to be different from one another. Making up my own syntax, I'd want something like:

type MyConfig = {
  [key: string]<Props, Config>: Element<Props, Config>
};

Is something like this possible to express in TS? How can I do so?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source