I'm trying to build a react component which shows a stack images, something like this, and for that, I'm trying to type it with interface and types to enforce taking some props in a particular way. Here's my interface code from before:
old-interface.ts
export interface ImageStackProps{
images: string[];
backgroundColor: string;
extraBannerBackgroundColor: string;
imageSize: ImageSize<string>;
imagesToShow: number;
direction?: StackDirection<"column" | "row" | "column-reverse" | "row-reverse">;
}
type StackDirection<T> = T | Array<T | null> | { [key: string]: T | null };
type ImageSize<T> = { width: T; height: T };
The imagesToShow property decides, how many images it's going to show and if it'll show the extra images remaining banner or not. Although it's not necessary, I was trying to constraint imagesToShow property based of the images property (which gets an array of base64 encoded images), so that a value larger than the last index of the array is never allowed. So, for that, I modified my interface to look something like this:
new-interface.ts
export interface ImageStackProps<ImagesArray extends Array<string>> {
images: ImagesArray;
backgroundColor: string;
extraBannerBackgroundColor: string;
imageSize: ImageSize<string>;
imagesToShow: AllowedArrayIndexes<ImagesArray>;
direction?: StackDirection<"column" | "row" | "column-reverse" | "row-reverse">;
}
type StackDirection<T> = T | Array<T | null> | { [key: string]: T | null };
type ImageSize<T> = { width: T; height: T };
type ArrayKeys<T extends Array<string>> = keyof T;
type AllowedArrayIndexes<T extends Array<string>> = Exclude<ArrayKeys<T>, ArrayKeys<string[]>>;
But the issue at this point that I'm facing is that to type my ImagesStack component, I need to pass a type to ImageStackProps, which is something that my ImagesStack components receive in its props.images.
I understand and know that it's not necessary to have this constraint and it works just fine without it, but I'm looking to see if I can achieve this. I'm pretty sure that I'm not approaching this correctly. Is there a better way to enforce this? Or better, is this even achievable somehow? How should I modify my interface?