Home > Back-end >  Use props from various interfaces, without naming them explicitly
Use props from various interfaces, without naming them explicitly

Time:01-25

Assuming I have this

interface ButtonProps {
    children?: React.ReactNode,
    backgroundColor?: Colors,
    style?: object,
    disabled?: boolean,
    classes?: string
    onClick?: () => void
}


const Button = ({
                        backgroundColor,
                        classes,
                        children,
                        disabled = false,
                        onClick,
                        style,
                    }: ButtonProps) => {

    const _constructInlineStyles = (): CSSProperties => {
        ...
    }

    return (
        <button
            className={clsx(classes, 'button-container')}
            disabled={disabled}
            onClick={onClick}
            style={...}>
                {children}
        </button>
    )
}

export default Button;

I then want to create a TextButton which uses builds on top of Button.

    interface TextButtonProps {
        children: string;
    }
    
    const TextButton = ({
                            children,
                        }: TextButtonProps) => {
        return (
            <Button>
                <Text>
                    {children}
                </Text>
            </Button>
        )
    }

export default TextButton;

Can one write it in a way, that the ButtonProps are made available to TextButton, without naming them. So instead of

    interface TextButtonProps {
        children: string;
    }
    
    const TextButton = ({
                            children,
                            backgroundColor,
                            classes,
                            disabled = false,
                            onClick,
                            style,
                        }: TextButtonProps & ButtonProps ) => {
        return (
            <Button
                 className={classes}
                 disabled={disabled}
                 onClick={onClick}
                 style={style}>
                <Text>
                    {children}
                </Text>
            </Button>
        )
    }

Something like

    interface TextButtonProps {
        children: string;
        props: ButtonProps;
    }
    
    const TextButton = ({
                            children,
                            props,
                        }: TextButtonProps) => {
        return (
            <Button
                 {...props}>
                <Text>
                    {children}
                </Text>
            </Button>
        )
    }

So that I can do

<TextButton 
    disabled={true} >
    Fooo
</TextButton>

?

CodePudding user response:

You can use the spread operator to receive the remaining props in the function call and to pass them to the Button component. To use the correct children type, refer to this answer using Omit:

import { Text} from 'react-native-paper'
interface ButtonProps {
  disabled?: boolean;
  onClick?: () => void;
  children: JSX.Element;
}

const Button = (props: ButtonProps) => {
  return <div>{props.children}</div>;
};

interface TextButtonProps extends Omit<ButtonProps, "children"> {
  children: string;
}

const TextButton = ({ children, ...props }: TextButtonProps) => {
  return (
    <Button {...props}>
      <Text>{children}</Text>
    </Button>
  );
};

const example = <TextButton disabled>Hi</TextButton>;

CodePudding user response:

You can extend interfaces while omitting a property as follows.

interface TextButtonProps extends Omit<ButtonProps, 'children'> {
        children: string;
}
  • Related