Negin Basiri
Negin Basiri

Reputation: 1375

How to descturcture an object in Typescript when properties are optional?

I have a generic component which has some optional properties, I need to destructure props but I get errors

    interface IScenarioPageProps extends IScenarioStateWithDispatch {
    isOverlayVisible?: boolean;
    renderOverlayContent?: () => void;
}

const Page = (props: IStepStateWithDispatch | IScenarioPageProps | ITaskStateWithDispatch) => {
    const { taskState, stepState, isOverlayVisible, renderOverlayContent } = props;
    const { selectedTaskId, selectedTask } = taskState;
    const { selectedStepId, selectedStep } = stepState;

    const style = StyleSheet.create({
        content: {
            'background-color': getTheme().palette.white,
            height: '100vh'
        }
    });

    return (
        <div className={css(style.content)}>
            {isOverlayVisible && <Modal>{renderOverlayContent()}</Modal>}
        </div>
    );
};

export default Page;

How can I destructure those optional properties without getting Typescript error?

enter image description here

Upvotes: 2

Views: 112

Answers (1)

Finesse
Finesse

Reputation: 10801

Because the Page component uses the renderOverlayContent prop regardless and the prop isn't presented in the IStepStateWithDispatch or ITaskStateWithDispatch type (that's the reason of the error), I can make a assumption that you want the Page component to require all the props of the interfaces IStepStateWithDispatch, IScenarioPageProps and ITaskStateWithDispatch.

If my assumption is correct, then you need to replace | with & in the props type declaration. It will tell TypeScript that the props object has the properties from all the interfaces.

const Page = (props: IStepStateWithDispatch & IScenarioPageProps & ITaskStateWithDispatch) => {
    // ...
}

If my assumption is not correct (the component is polymorphic), then you need to check that the renderOverlayContent prop is given and then use it:

// ...

// const {renderOverlayContent} = props; // Remove this

return (
    <div className={css(style.content)}>
        {isOverlayVisible &&
            <Modal>
                {'renderOverlayContent' in props && props.renderOverlayContent && props.renderOverlayContent()}
            </Modal>
        }
    </div>
);

Upvotes: 1

Related Questions