No Overload Matches this call with Vue 3 ref<T>

Viewed 2818

I have the following types defined and I am trying to use with ref and don't want to define all the props default value initially, but I am TS error: No Overload Matches this call

interface EmailReminder {
  bcc_emails: string[] | null;
  cc_emails: string[];
  from_email: string;
  message: string;
  offset_days: number;
  subject: string;
  to_emails: string[];
  sent_at: string | Date;
  uuid: string;
}

And when I am trying to create a reactive variable with Vue 3 ref, by passing my type in place of generic, the typescript gets angry and throws the following error.

const reminder = ref<EmailReminder>({
      to_emails: [],
      cc_emails: [],
      message: '',
      subject: '',
    });

enter image description here

Could someone please tell me what I am doing wrong here, I don't want to make some properties optional and event don't want to use as to remove them.

2 Answers

They are not the same type, you are defeating the purpose of typescript here. Maybe just stick to javascript if you do not want objects to be strictly type defined. Your trying to assign 2 different types here is what the compiler picks up.

The ones missing need to be optional or you will get this error no matter what.

interface EmailReminder {
  cc_emails: string[];
  message: string;
  to_emails: string[];
  subject: string;
  bcc_emails?: string[] | null;
  from_email?: string;
  offset_days?: number;
  sent_at?: string | Date;
  uuid?: string;
}

alternatively you could initialize the other values as undefined

const reminder = ref<EmailReminder>({
      to_emails: [],
      cc_emails: [],
      message: '',
      subject: '',
      bcc_emails: undefined
      from_email: undefined;
      offset_days: undefined;
      sent_at: undefined;
      uuid: undefined;
    });

If you really really do not want to do the above I guess you could technically create 2 types and allow it to be either

interface BaseEmailReminder {
  cc_emails: string[];
  message: string;
  to_emails: string[];
  subject: string;
}

interface ExtendedEmailReminder extends BaseEmailReminder {
  bcc_emails: string[] | null;
  from_email: string;
  offset_days: number;
  sent_at: string | Date;
  uuid: string;
}

and then go

const reminder = ref<BaseEmailReminder | ExtendedEmailReminder>({
      to_emails: [],
      cc_emails: [],
      message: '',
      subject: '',
    });

Id recommend going with the optional members though because the second 2 examples are kind of anti pattern hacks that don't really follow typescript behaviour properly and is not best practices as by not having those members your saying they are optional.

I was able to come up with a solution that we use in my current organization as a standard form.

It's simply not necessary to define inner initial values within the ref.

Example:

ref<EmailReminder>()

I know the value of the variable will be undefined, but it's the best that I came across.

Related