1

I have a map of components like this:

import { Select, Input, DatePicker } from 'antd';

const MyComponentMap = {
   Select,
   Input,
   DatePicker
}

I'm trying to create a JSON structure like this:

const myFields: MyTypes<typeof MyComponentMap> = {
    address1: {
        component: {
          type: 'Input', <- string name
          props: {
            // input props
          }
        } 
    },
    when: {
       component: {
          type: 'DatePicker',
          props: {
            // DatePikcer props
          }
       }
    }
}

The important part is that I want to create a MyTypes type that uses MyComponentMap to infer the correct prop types, but I'm failing. I have something like this:

type ComponentMap = Record<string,React.ComponentType>

type MyTypes<Components extends ComponentMap> = Record<string,MyField<Components>>

type MyField<Components extend ComponentMap> = {
    component: MyFieldConfig<Components>,
    ...other things
}

And here's MyFieldConfig:

type MyFieldConfig<Components extends ComponentMap> = {
   type: keyof Components;
   props: Partial<React.ComponentProps<keyof Components>>
}

Obviously that doesn't work because props isn't tied to the key from the ComponentMap (so I can set

{
   type: "Input",
   props: { ...props for a Select }
}

I also tried

type MyFieldConfig<Components extends ComponentMap, R = keyof Components> = {
   type: R;
   props: Partial<React.ComponentProps<Components[R]>>
}

but I got type R cannot be used to index Components

How can I achieve the inference I'm looking for?

7
  • Are antd and React required for this question? If so you should probably tag it as such; if not, please remove your example code's dependence on them so we can quickly reproduce the issue in a standalone IDE. Commented May 15, 2022 at 1:17
  • @jcalz They are not required, per se, just happens to be the specific problem I am encountering. I'll try to replace the types with something more generic. Thanks for your comment! Commented May 15, 2022 at 1:19
  • 2
    Does this approach meet your needs? If so I can write up an answer explaining it (after you clean up the question); if not, what am I missing? Note that you have a property named component but your MyFieldConfig doesn't mention component at all... could you rectify that (preferably by removing the extra level of nesting unless its presence is necessary)? Commented May 15, 2022 at 1:22
  • @jcalz yes! I just verified that approach works. What wizardry is this?!? Commented May 15, 2022 at 1:30
  • 1
    Hmm, maybe you could remove stuff instead of add it (the fact that you have an extra nested layer with a component property isn't what you're asking about, right?), and please be sure you have posted a minimal reproducible example; a typo like Components extend ComponentMap just makes things harder on me. Ideally I can just drop your code into a standalone IDE, with no external dependencies like antd and react, fix the type mapping bit, and write up an answer explaining how just that part works. I'll check back in later to see if things have improved here. Good luck! Commented May 15, 2022 at 1:39

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.