I am still very new to programming and typescript. I hope I can explain my question reasonably well, unfortunately I could not find a solution online.
I have a value variable like this for emails:
contactId: string | undefined;
from: string;
to: string;
cc: string;
send?: boolean;
I have a sendMail
function that I use very often and want to keep instead of making two new functions.
This sendMail
function gets a mail
object passed to it and then uses the values to send a mail.
The problem now is that sometimes the values are in mail
and sometimes in mail.mutateMail
.
If I need for example the ID of the mail, it can be that I get it from mail.id
or mail.mutateMail.id
.
But it is always either or, not both.
This also works I cannot make the function typesafe like this.
Actually I need something like this:
export const sendMail =
(mail: ValuesType, mail.mutateMail: ValuesType): AppThunk =>
{
const mailId = !mail.mutateMail ? mail.id : mail.mutateMail.id;
console.log(mailId)
}
But of course this does not work.
Can someone please tell me what is the best thing to do in this case to make the function typesafe?
But it is always either or, not both.
You are describing a union.
Your value can be one of two things. So you have two members in the union.
type ValuesOrNested =
(ValuesType & { mutateMail?: never }) | { mutateMail: ValuesType }
That says the value can be one of two types.
The first member type is your ValuesType
object that does not have a mutateMail
property. The second member type can be an object with a mutateMail
property that that is ValuesType
.
Now you can use that type for your argument:
export const sendMail =
(mail: ValuesOrNested): AppThunk =>
{
const mailId = !mail.mutateMail ? mail.id : mail.mutateMail.id;
console.log(mailId)
}
And the function should allow either format, but not both:
// These work
sendMail({ id: 1, contactId: 'qwe', from: 'a', to: 'b', cc: 'd' })
sendMail({ mutateMail: { id: 1, contactId: 'qwe', from: 'a', to: 'b', cc: 'd' } })
// error as expected
sendMail({
id: 1, contactId: 'qwe', from: 'a', to: 'b', cc: 'd',
mutateMail: { id: 1, contactId: 'qwe', from: 'a', to: 'b', cc: 'd' }
})