mcclosa
mcclosa

Reputation: 1455

Using Union for function arg throwing type errors

I have the following types that are setup to handle 2 different form submissions with 2 different objects as the argument in a function.

interface FormValues {
  firstNames: string;
  middleNames: string;
  surname: string;
}

interface PasswordFormValues {
  password: string;
  confirmPassword: string;
}

type FormSubmit = (values: FormValues | PasswordFormValues) => Promise<void>

interface ProfileFormProps {
  onFormSubmit: (values: FormValues | PasswordFormValues) => Promise<void>;
}

However trying it pass in either type for the argument in the function using the FormSubmit type, I get the following Type error.

Type '(values: PasswordFormValues) => Promise<void>' is not assignable to type '(values: FormValues | PasswordFormValues) => Promise<void>'.
  Types of parameters 'values' and 'values' are incompatible.
    Type 'FormValues | PasswordFormValues' is not assignable to type 'PasswordFormValues'.
      Type 'FormValues' is missing the following properties from type 'PasswordFormValues': password, confirmPassword
const formValues: FormValues = {
  firstNames: 'Name',
  middleNames: '',
  surname: 'Surname'
};

const passwordFormValues: PasswordFormValues = {
  password: 'password',
  confirmPassword: 'password'
};

const updatePassword = async (values: PasswordFormValues) => {};

const props: ProfileFormProps = {
  onFormSubmit: updatePassword
}

How can I pass either object as the argument in a function using the FormSubmit type?

I have a TypeScript Playground URL with the issue

Upvotes: 0

Views: 34

Answers (1)

Sean Vieira
Sean Vieira

Reputation: 159905

Simply change your handler to take either a handler for a FormValues or a PasswordFormValues:

interface ProfileFormProps {
  onFormSubmit: ((values: FormValues) => Promise<void>) | ((values: PasswordFormValues) => Promise<void>);
}

That said, this opens you up to someone configuring a form that only produces FormValues and providing an onFormSubmit that only consumes PasswordFormValues. Ideally you'd use correlated union types a la Joe Calzaretta's microsoft/typescript#30581

Upvotes: 1

Related Questions