Eine aktualisierte Antwort: da die Zugabe von Kreuzungstypen über &, ist es möglich, zwei abgeleitete Typen on the fly „verschmelzen“.
Hier ist ein allgemeiner Helfer, die die Eigenschaften eines Objekts liest fromund kopiert sie auf ein Objekt onto. Es gibt das gleiche Objekt , ontoaber mit einer neuen Art , die beiden Arten von Eigenschaften enthalten, so richtig das Laufzeitverhalten beschreiben:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
Diese Low-Level-Helfer nicht durchführt noch eine Art Behauptung, aber es ist typsicher durch Design. Mit diesem Helfer an Ort und Stelle haben wir einen Operator, dass wir die OP das Problem zu lösen, mit voller Typsicherheit verwenden:
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}`)
}
}
);
Klicken Sie hier , um es auszuprobieren im Typoskript Spielplatz . Beachten Sie, dass wir gezwungen foovom Typ zu sein Foo, so das Ergebnis mergehat eine vollständig zu sein Foo. Also , wenn Sie umbenennen , barum baddann erhalten Sie einen Typfehler.
NB Es gibt immer noch eine Art Loch hier jedoch. Typoskript bietet keine Möglichkeit , einen Typ - Parameter zu beschränken „keine Funktion“ zu sein. So könnten Sie verwirren und Ihre Funktion als zweites Argument übergeben zu merge, und das würde nicht funktionieren. Also , bis diese deklariert werden können, müssen wir es zur Laufzeit fangen:
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;
}