1

Spectrum uses specific pattern for modals which I would like to replicate with typescript, graphQL and graphQL-codegen generated hooks.

Now what I currently have:

  • GraphQL Client Schema
enum ModalType {
  LOGIN,
  SIGNUP,
}

type LoginModalProps{
  loginVal: String!
}

type SignupModalProps{
  signupVal: String!
}

extend type Query {
  openedModal: OpenedModal!
}

union ModalProps = LoginModalProps | SignupModalProps

type OpenedModal {
  modalType: ModalType!
  modalProps: ModalProps!
}
  • GraphQL Query
export const GET_OPENED_MODAL = gql`
  query OpenedModal{
    openedModal @client{
      modalType,
      modalProps{
        ... on LoginModalProps {
          loginVal
        }
        ... on SignupModalProps {
          signupVal
        }
      }
    }
  }
`;

Code above is used by graphql-codegen for generating type safe query hook used below.

import React from 'react';
import LoginModal from '../containers/modals/LoginModal';
import SignupModal from '../containers/modals/SignupModal';
import { 
  useOpenedModalQuery, 
  ModalType, 
  LoginModalProps, 
  SignupModalProps 
} from '../../generated/graphql';

const ModalContainer: React.FC = () => {
  const { data } = useOpenedModalQuery();

  switch(data?.openedModal.modalType){
    case ModalType.Login:
      return <LoginModal {...data?.openedModal.modalProps as LoginModalProps}/>

    case ModalType.Signup:
      return <SignupModal {...data?.openedModal.modalProps as SignupModalProps}/>

    default: 
      return null;
  }
}

export default ModalContainer

Given modal declaration then looks as follows

import { LoginModalProps } from '../../../generated/graphql';

const LoginModal: React.FC<LoginModalProps> = ({
  loginVal
}) => {

I am new in this typed and graphQL world and it feels to me that it could be done better - especially the switch case statement that I had to use instead of the original object. Is there some way how to preserve coupling between ModalType and ModalPropsType? And is the code still safe with the as casting on ModalProps?

0 Answers0