Dieterg Dieterg - 1 month ago 26
TypeScript Question

Advanced TypeScript argument constraints

I'm wondering if somethings as follows is possible in TypeScript,
What I'm trying to achieve:


  1. If the
    type
    is
    inbox
    then
    obj
    should be of type interface
    IInbox
    .

  2. If the
    type
    is
    sent
    then
    obj
    should be of type interface
    ISent
    .






interface IInbox {

}

interface ISent {

}

class MailClient {
delete(type: "inbox" | "sent", obj: IInbox | ISent) {

}
}

let client = new MailClient();
client.delete('inbox', <ISent>{}); // should give compile error

Answer

You can define multiple signatures:

class MailClient {
    delete(type: "inbox", obj: IInbox);
    delete(type: "sent", obj: ISent)
    delete(type: "inbox" | "sent", obj: IInbox | ISent) {}
}

But that still won't have a compilation error because your interfaces are identical.
Because typescript is using duck typing then the empty object ({}) satisfies the type requirements.
If you differentiate between the two:

interface IInbox {
    a: string;
}

interface ISent {
    b: string;
}

Then you get your error:

client.delete('inbox', {} as ISent); // Argument of type '"inbox"' is not assignable to parameter of type '"sent"'

(code in playground)