Home > Software design >  How do dynamically access a type via function parameter
How do dynamically access a type via function parameter

Time:11-19

I have something like the following:

const activeFormDesign = {
    fields: {
    },
    elements: {
    },
    groups: {
    },
    layouts: {
        section: SectionLayout,
        header: Header,
        title: Title,
        description: Description,
        goal: Goal,
    },
};

Each property of layouts refers to a functional component with distinct props. My goal is that someone can access the FC of a given layout by providing the key, and the returned FC will know what props its supposed to have.

I thought I could do something like this:

export function getLayoutTemplate(type: keyof typeof activeFormDesignTemplate['layouts']): FC<typeof activeFormDesignTemplate['layouts'][type] {
    return activeFormDesignTemplate.layouts[type];

}

const Goal = getLayoutTemplate('goal');

<Goal />

The parameter type works great. But the return type throws an error that "type cannot be used as an index type". I mean... it kind of makes sense. I understand that a truly dynamic type couldn't be inferred. But if I'm statically typing it out, as in getLayoutTemplate('goal') I would think that it could.

I feel like there's a way to do this, but I've not quite figured it out and would appreciate any help!

CodePudding user response:

Assuming that SectionLayout, Header, etc. are already of type React.FC, you only need to make the function generic over K and remove the React.FC around the return type.

export function getLayoutTemplate<
  K extends keyof typeof activeFormDesign["layouts"]
>(type: K): typeof activeFormDesign['layouts'][K] {
    return activeFormDesign.layouts[type];
}

The parameter type is now of type K and you can use K to index typeof activeFormDesign['layouts'] for the return type.

But you are gonna need to find a way at runtime to convert whatever SectionLayout, Header, etc. are into a React.FC if they are not already of type React.FC


Playground

  • Related