A frissített válasz: mivel hozzáadásával kereszteződés típusok keresztül &, lehetőség van a „merge” két kikövetkeztetett típusú menet közben.
Itt egy általános segítőt, hogy beolvassa a tulajdonságait valami tárgyat from, és átmásolja egy objektum fölé onto. Ugyanazokat az objektumot onto, hanem egy új típusú, amely magában foglalja mindkét tulajdonságait, így pontosan leírja a futási viselkedés:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
Ez az alacsony szintű helper nem is végrehajthatja a típus-állítás, de ez típus-biztonságosnak design. Ezzel a segítő a helyén, van egy operátor, hogy tudjuk használni, hogy megoldja a problémát OP teljes típus biztonság:
interface Foo {
(message: string): void;
bar(count: number): void;
}
const foo: Foo = merge(
(message: string) => console.log(`message is ${message}`), {
bar(count: number) {
console.log(`bar was passed ${count}`)
}
}
);
Kattintson ide, hogy próbálja ki a géppel Playground . Figyeljük meg, hogy akadályozza a footípusúnak Foo, így az eredmény mergekell, hogy legyen egy teljes Foo. Tehát, ha átnevezi bara badakkor kap egy típus hiba.
NB : Még van egy lyuk típusú van, de. Géppel nem nyújt olyan módon, hogy korlátozzák a típusú paraméter, hogy „nem egy funkció”. Így lehet összezavarodnak, és adja át a funkciója, mint a második argumentum merge, és hogy ez nem működik. Tehát, amíg ez lehet nyilvánítani, meg kell fogni, hogy a futás:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
if (typeof from !== "object" || from instanceof Array) {
throw new Error("merge: 'from' must be an ordinary object");
}
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}