I encountered a problem in Typescript that I couldn't find a solution to.
I have a React component, and I want to load it with different props, depending on its "type" prop.
For example:
interface PropsA {
a: string;
}
interface PropsB {
b: string;
}
type Props<T extends string> = { type: T } & (T extends 'A' ? PropsA : PropsB);
class Component<T extends string> extends React.Component<Props<T>> {};
So, the expected behavior is - when the type prop equals to "A", I want the component allowed (and required) props to be only 'a' and not 'b'. However, when I try to use this component and set its type to "A", I can render it with the 'b' prop without a problem.
const App = () => {
return (
<Component type="A" b="whatever" />
)
}
** NO ERROR!
However, if I change things a bit, so that the conditional props will render inside another prop, it will work:
type Props<T extends string> = { type: T } & { extraProp: T extends 'A' ? PropsA : PropsB };
class Component<T extends string> extends React.Component<Props<T>> {};
const App = () => {
return (
<Component type="A" extraProp={{ b: 'whatever' }} />
)
}
** ERROR! (this is good, that means I can only use 'a' inside 'extraProp' like I wanted to.
Also, in the Props type, if I change the intersection to union, it will work, but the required prop 'a' or 'b' will now be optional, and that's not what I want.
Why is that so? Is that some bug or am I missing something?
Just found that using:
Instead of:
Solved the problem. But why? Shouldn't it work also with the class implementation?