Avancerade TypeScript-argumentbegränsningar
Jag undrar om något som följer är möjligt i TypeScript, vad jag försöker uppnå:
- Om
typeärinboxskaobjvara av typen interfaceIInbox. - Om
typeärsentdå börobjvara av typen gränssnittISent.
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
Svar #1
Du kan definiera flera signaturer:
class MailClient {
delete(type: "inbox", obj: IInbox);
delete(type: "sent", obj: ISent)
delete(type: "inbox" | "sent", obj: IInbox | ISent) {}
}
Men det kommer fortfarande inte att ge ett kompilationsfel eftersom dina gränssnitt är identiska.
Eftersom TypeScript använder duck typing så uppfyller det tomma objektet ({}) typkraven.
Om du skiljer mellan de två:
interface IInbox {
a: string;
}
interface ISent {
b: string;
}
Då får du ditt fel:
client.delete('inbox', {} as ISent); // Argument of type '"inbox"' is not assignable to parameter of type '"sent"'
(kod i lekplats)
Svar #2
Såvitt jag vet är denna begränsning inte möjlig, ändå kan du enkelt skriva en mycket enkel lösning som följer:
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;
}
}
Detta skulle göra ditt jobb på ett ganska läsbart sätt.
