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 CustomImageComponentProps
accoding 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 theCustomImageComponentProps
required 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.