given the following type definition
type MailStatus = {
InvoiceSent?: Date;
ReminderSent?: {
date: Date;
recipient: string;
}
FinalReminderSent?: {
date: Date;
recipient: string;
text: string;
}
}
I'd like to have type where I can define the "order" in which a property is required and which creates a discriminated union which have ever more required properties.
For example
type OrderedMailStatus = MagicType<MailStatus, "InvoiceSent" | "ReminderSent" | "FinalReminderSent">
//or this
type OrderedMailStatus = MagicType<MailStatus, ["InvoiceSent", "ReminderSent","FinalReminderSent"]>
should yield the following type
type OrderedMailStatus =
| {
kind: "InvoiceSentRequired";
InvoiceSent: Date; //InvoiceSent now required
ReminderSent?: {
date: Date;
recipient: string;
};
FinalReminderSent?: {
date: Date;
recipient: string;
text: string;
};
}
| {
kind: "ReminderSentRequired";
InvoiceSent: Date; //InvoiceSent required
ReminderSent: { //ReminderSent also required
date: Date;
recipient: string;
};
FinalReminderSent?: {
date: Date;
recipient: string;
text: string;
};
}
| {
kind: "FinalReminderSentRequired";
InvoiceSent: Date; //all
ReminderSent: { //3 properties
date: Date;
recipient: string;
};
FinalReminderSent: { //are required
date: Date;
recipient: string;
text: string;
};
}
so that I could do the following assignments
const s1 = {
kind: "InvoiceSentRequired",
InvoiceSent: new Date()
} //OK
const s2 = {
kind: "ReminderSentRequired",
InvoiceSent: new Date(),
ReminderSent: {
date: new Date(),
recipient: "Somebody@somewhere.com"
}
} //OK
const s3 = {
kind: "FinalReminderSentRequired",
ReminderSent: {
date: new Date(),
recipient: "Somebody@somewhere.com"
},
FinalReminderSent: {
date: new Date(),
recipient: "Somebody@somewhere.com",
text: "YOU HAVE TO PAY!"
}
} //FAILS because it is missing the property InvoiceSent
Also important: The types of the properties should be automatically taken what ever they are in the original MailStatus. So even in this expanded example you can not make any assumptions which property has which type.
The principle idea behind this question is something along the lines of a Workflow. Where in the beginning you have a type whose properties are all optional. As this type travels across the system more and more properties become mandatory