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
 
     
    