I want to be able to add additional constraints/types to my interface when a union type property is a particular value. Is this possible in Typescript?
So as a concrete example... If I have a type TypographyProps
and it has a variant
property in it of a union type. How can I use that variant
property to extend the TypographyProps
to include another type?
export interface TypographyProps extends ParentProps {
variant?: "h1" | "h2" | "h3" | "p" | "span";
color?: keyof Theme["colors"];
spacing?: Theme["spacing"];
wrap?: boolean;
}
// How can I add in the type def for each type `JSX.IntrinsicElements["h2"]`, etc... based on `variant`?
I ended up going with this solution. It is very similar to Tushar Shahi's answer above but I needed to be more explicit with strings in each type rather than create a new Variant
type that has everything.
type HeadingVariantProps = {
variant: "heading" | "subheading" | "title" | "subtitle";
ref?: Ref<HTMLHeadingElement>;
};
type BodyVariantProps = {
variant: "body";
ref?: Ref<HTMLParagraphElement>;
};
type DefaultVariantProps = {
variant?: undefined;
ref?: Ref<HTMLSpanElement>;
};
export type TypographyProps = ParentProps & {
color?: keyof Theme["colors"];
spacing?: Theme["spacing"];
wrap?: boolean;
} & (HeadingVariantProps | BodyVariantProps | DefaultVariantProps);