高级TypeScript参数约束

时间:2016-10-17 18:08:40

标签: typescript

我想知道在TypeScript中是否可以使用以下某些东西, 我想要实现的目标:

  1. 如果typeinbox,则obj应为接口IInbox类型。
  2. 如果typesent,则obj应为接口ISent类型。
  3. 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
    

2 个答案:

答案 0 :(得分:3)

您可以定义多个签名:

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

但由于您的界面相同,因此仍然没有编译错误 因为typescript使用duck typing,所以空对象({})满足类型要求 如果你区分两者:

interface IInbox {
    a: string;
}

interface ISent {
    b: string;
}

然后你得到错误:

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

code in playground

答案 1 :(得分:0)

据我所知,这种约束是不可能的,无论如何,您可以轻松编写一个非常简单的解决方法,如下所示:

class MailClient {
    delete(type: "inbox" | "sent", objI?: IInbox, objS?: ISent) {
        if ((type === "inbox" && typeof objS !== "undefined") ||
                 type === "send" && typeof objI !== "undefined") {
            throw new "Invalid parameter";    
        }
        let obj = (type === "inbox") ? objI : objS;
    }
}

这将以一种可读的方式完成你的工作。