ARTICLE AD BOX
Can this React component be typed, such that if the Renderer component is defined, itemList can only be an array of parameters for Renderer, and if Renderer is undefined, itemList can only be an array of strings?
export const ListRenderer = ({itemList, Renderer}) => { if (Renderer === undefined) { return <ul> {itemList.map(i => <li>{i}</li>)} </ul> } else { return <ul> {itemList.map(i => <li><Renderer {...i} /></li>)} </ul> } };The component should accept {itemList: str[]} and {itemList: T[], Renderer: FC<T>} but not {itemList: str[], Renderer: FC<T>}. The first branch should narrow i to have type string, and the second branch should narrow i to have type T. Note that T extends IntrinsicAttributes & {key: Key}
207k20 gold badges284 silver badges294 bronze badges
I suppose you could define the ListRenderer props to be a union of { itemList: string[]; Renderer?: undefined } or { itemList: string[]; Renderer?: never }, and { itemList: T[]; Renderer: React.FC<T> } so it's one or the other.
Example:
type BaseType = JSX.IntrinsicAttributes & { key: React.Key }; type ListRendererProps<T extends BaseType> = | { itemList: T[]; Renderer: React.FC<T> } | { itemList: string[]; Renderer?: never }; const ListRenderer = <T extends BaseType>({ itemList, Renderer, }: ListRendererProps<T>) => { if (Renderer === undefined) { return ( <ul> {itemList.map((i) => ( <li>{i}</li> ))} </ul> ); } else { return ( <ul> {itemList.map((i) => ( <li> <Renderer {...i} /> </li> ))} </ul> ); } };Examples:
itemList is string[], Renderer is undefined (happy path):
itemList is string[], Renderer is defined (sad path, the one you want to avoid/omit):
itemList is not string[], Renderer is defined (other happy path):
207k20 gold badges284 silver badges294 bronze badges
Explore related questions
See similar questions with these tags.

![itemList is string[], Renderer is undefined (happy path)](https://i.sstatic.net/51620NpH.png)
![itemList is string[], Renderer is defined (sad path, the one you want to avoid/omit)](https://i.sstatic.net/trLv0OLy.png)
![itemList is not string[], Renderer is defined (other happy path)](https://i.sstatic.net/gwQagAMI.png)