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