Search code examples
typescripttypescript-typingsfactoryunion-typestypescript-types

TypeScript: Factory function for union types


I have a custom Factory type that lets me create factory functions.

export type Factory<T> = (state?: Partial<T>) => T;

I have an <Avatar /> React component that has a union type as prop because there can be two versions of it (just the image, or clickable image). In other words, the component can have either or props.

type AvatarOnlyProps = {
  alt: string;
  src: string;
};

type ClickableAvatarProps = {
  alt: string;
  label: string;
  onClick:
    | ((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void)
    | undefined;
  src: string;
};

export type AvatarProps = AvatarOnlyProps | ClickableAvatarProps;

I want to create a factory function for the avatar's props. I tried typing it like this:

const createProps: Factory<AvatarProps> = ({
  alt = 'Your avatar',
  label,
  onClick,
  src: source = '/images/default-avatar.png',
} = {}) => ({ alt, label, onClick, src: source });

But TypeScript complains:

Property 'label' does not exist on type 'Partial<AvatarOnlyProps> | Partial<ClickableAvatarProps>'.

in the arguments of the factory function.

enter image description here

How can I make the error go away? How can I get TypeScript to under stand, that in this factory function either both onClick and label will be supplied, or neither?


Solution

  • I was able to solve it for my use case by creating the factor function with the minimal keys populated:

    const createProps: Factory<AvatarProps> = ({
      alt = 'Your avatar',
      src: source = '/images/default-avatar.png',
      ...props
    } = {}) => ({
      alt,
      src: source,
      ...props,
    });