J'ai un composant conteneur de boutons React qui renvoie un bouton normal, un bouton icône ou un bouton icône uniquement en fonction du type fourni par l'accessoire utilisé par l'utilisateur. Voici les définitions de types pertinentes pour ButtonContainer
组件与Props
:
type ButtonWrapperProp = { label?:string; icon?:React.ReactNode; onClick:()=>void; type:'text'|'icon'|'iconOnly'; } export const ButtonContainer = (props: ButtonWrapperProps) => { const { type = 'text', onClick, icon = <></>, label = '', } = props; const rendorButton = () => { switch (type) { case 'text': return ( <Button onClick={onClick}>{label} <Button/> ); case 'iconOnly': return ( <IconButton onClick={onClick}> {icon} </IconButton> ); case 'icon': return ( <Button startIcon={icon}> {label} </Button> ); default: return ( <Button onClick={onClick}>{label} <Button/> ); } }; return <>{rendorButton()}</>; };
Voici comment j'utilise le composant ButtonContainer :
<ButtonContainer type="iconOnly" onClick={onClick} icon={<DeleteIcon />}/> <ButtonContainer type="text" onClick={onClick} label='Text button'/> <ButtonContainer type="icon" onClick={onClick} label='Text and icon button' icon={<DeleteIcon />}/>
Dans le code ci-dessus, l'accessoire icône est facultatif car il n'est utilisé que pour les boutons d'icônes et les boutons normaux avec des icônes. Je souhaite que le accessoire d'icône soit facultatif uniquement si le type transmis par ButtonContainer est du texte et il devrait s'agir d'un accessoire obligatoire si le type transmis à ButtonContainer est une icône ou iconOnly.
Je choisirais d'utiliser Distinguish Union Type.
L'attribut type agit comme un discriminateur, vous permettant de limiter ButtonWrapperProps aux membres du syndicat.
Notez également que je peux rendre obligatoires les propriétés de chaque membre du syndicat, ce qui donne une expérience agréable lors de leur utilisation - TS est suffisamment intelligent pour indiquer quelles propriétés supplémentaires sont requises une fois le type défini.