tonytin
tonytin

Reputation: 1

What are some effective strategies for handling mutually exclusive properties in React with Typescript, with an aim to improve developer experience?

I'm currently working on a React project using TypeScript and am encountering an issue regarding the management of mutually exclusive props. My aim is to find a more effective strategy to handle these, with a focus on improving the overall developer experience. I'm aware that handling mutually exclusive properties can sometimes be tricky and can introduce additional complexity into the codebase. Therefore, I am looking for ways to make this process more streamlined and less prone to errors and complexity.

Let's suppose i have MyComponent like this:

interface CommonProps {
    commonProp1: string;
    commonProp2: string;
    commonProp3: string;
}

interface Component1Props extends CommonProps {
    component1Prop1?: string;
    component1Prop2?: string;
    component1Prop3?: string;
    component2Prop1?: never;
    component2Prop2?: never;
    component2Prop3?: never;
    
}

interface Component2Props extends CommonProps {
    component2Prop1?: string;
    component2Prop2?: string;
    component2Prop3?: string;
    component1Prop1?: never;
    component1Prop2?: never;
    component1Prop3?: never;
}

type ComponentProps = Component1Props | Component2Props;

const MyComponent: FC<ComponentProps> = ...

In the above code, it seems complex to me, and I'm not a fan of having every prop suggested by TypeScript's autocomplete feature. For instance, if I declare component1Prop1, I don't want to see the ones put to never ( but this is another topic, since we have to list every props in the FC)

Now, I've been considering a different approach, but I'm not sure if it can be feasibly implemented:

interface Props {
    prop1: string;
    prop2: string;
    prop3: string;
    prop4: string & Red;
    prop5: string & Red;
    prop6: string & Red;
    prop7: string & Blue;
    prop8: string & Blue;
    prop9: string & Blue;
    prop10: string & Orange;
    prop11: string & Orange;

}


const MyComponent: TFC<Props> = ({
    disable: {
        Red: { Blue, Orange}
    },
    allow: {
        Red : { Orange['prop11'] }
    }
})
...

EDIT: more information about my intent: a compile-time mechanism to enforce mutually exclusive properties within the React props based on custom types like Red and Blue.

interface MyProps {
    prop1: string;
    prop2: string;
    prop3: string;
    prop4?: string & Red;
    prop5?: string & Red;
    prop6?: string & Red;
    prop7?: string & Blue;
    prop8?: string & Blue;
    prop9?: string & Blue;
}

type Red = { __red: true };
type Blue = { __blue: true };

type PropSet<N, T> = { [P in keyof N]: N[P] extends T ? never :  N[P] };

type Disabled<P> = {
    [K in keyof P]: P[K] extends Red ? PropSet<P, Blue> : P[K] extends Blue ? PropSet<P, Red> : P[K];
}


const MyComponent = (props: Disabled<MyProps>) => {
    return <div>MyComponent</div>
}

export default MyComponent;

However i dont get errors when i create the component and the two props are from different colors:

 <MyComponent prop1="none" prop2="none" prop3="none" prop4="red" prop8="blue"/> // no error

The key concept involves disabling certain properties marked with a tag (which could be anything not just colors ), and allowing exceptions in certain cases in a very easy way. This could potentially reduce the risk of incorrect property assignment and enhance autocompletion features even for the most unexperied devs.

What are your thoughts on this approach? Can it be feasibly implemented? Are there other strategies or best practices that you have used to handle mutually exclusive properties that improved your developer experience? I look forward to hearing your insights and recommendations.

Upvotes: 0

Views: 131

Answers (0)

Related Questions