Home > database >  define optional props based on other props for react component
define optional props based on other props for react component

Time:12-16

I have a component that has a loading state and I have isLoading prop that determines that component is loading or not:

    interface CustomImageComponentProps {
    isLoading:boolean
    src:string
    description:string
}

export const MyCustomImage = ({isLoading}:CustomImageComponentProps) => {

   
    return (
        <If condition={isLoading} OnTrue={
            <Shimmer/>
        } OnFalse={//other content}/>

    );
});

Basically, I want to make other props optional if isLoading is true. How can I achive this behavior using typescript?

CodePudding user response:

This is how I made. A loadinglayout to wrap some of my components. If loading is true, components won't be shown. There is another approach if you don't like this. You can use style={{display: loading ? 'none' : 'flex'}}.

interface LoadingLayoutProps extends ELoadingProps {
  loading?: boolean;
  LoadingComponent?: React.ReactNode;
  children?: any;
  // other props
}

function LoadingLayout(props: LoadingLayoutProps) {
  const { loading = false, LoadingComponent = <ActivityIndicator />, children } = props;

  if (loading) {
    return (
      <LoadingComponent />
    );
  }

  return <>{children}</>;
}

function App() {
  const [state,setState] = React.useState(true);

  return (
    <LoadingLayout loading={loading}>
      <YourOtherComponents />
    </LoadingLayout>
  )
}

CodePudding user response:

Hi @reza47,

If I understand correctly. Then, that is the one answer which is satisfying you. Definitely.

If you want to make props optional, if only if When isLoading is true. Then, you need some little more work like this.

type RequiredProps = {
  src: string;
  description: string;
}

I'm not sure. But, RequiredProps is overriding the CustomImageComponentPropsaccoding to me. I don't know how its work, indeed. If anyone knows about that. Then, I will appreciate anyone's reply.

interface CustomImageComponentProps {
  isLoading: boolean;
  src?: string;
  description?: string;
} & (isLoading extends false ? RequiredProps : {})

but the thing is theCustomImageComponentPropsrequired isLoading condition. That doesn't mean.

you don't need to import the isLoading component implicitly in order to use it in the type assertion for the CustomImageComponentProps interface.

In TypeScript, the type of a value is determined by the type of the variable that holds the value. rather than by the value itself.

CodePudding user response:

The type system term for what you want is a "discriminated union," where a value could be one of two or more types, determined by the value of one type.

type LoadedImage = {
  isLoading: false;
  src: string;
  description: string;
}

type PendingImage = {
  isLoading: true;
  src?: string;
  description?: string;
}

type CustomImageComponentProps = LoadedImage | PendingImage

now if isLoading is false, you (and typescript) know that src and description are available. if you don't check for isLoading, you'll still have to handle the possibility of undefined src and description, or at least you'll have to turn off the typescript alerts.

  • Related