Una risposta aggiornata: poiché l'aggiunta di tipi di intersezione tramite &
, è possibile "unire" due tipi dedotti al volo.
Ecco un helper generale che legge le proprietà di alcuni oggetti from
e li copia su un oggetto onto
. Restituisce lo stesso oggetto onto
ma con un nuovo tipo che comprende due serie di proprietà, così correttamente descrivere il comportamento di compressione:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
Questo helper basso livello non ancora eseguire un tipo affermazione, ma è del tipo sicuro dal design. Con questo helper in atto, abbiamo un operatore che possiamo utilizzare per risolvere il problema del PO, con la sicurezza di tipo integrale:
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}`)
}
}
);
Click here to try it out in the TypeScript Playground. Si noti che abbiamo limitato foo
per essere di tipo Foo
, quindi il risultato di merge
deve essere uno Foo
completo. Quindi se si rinomina bar
in bad
si ottiene un errore di tipo.
NB C'è ancora un tipo di foro qui, tuttavia. TypeScript non fornisce un modo per vincolare un parametro di tipo "non una funzione". Quindi potresti confondermi e passare la tua funzione come secondo argomento a merge
, e questo non funzionerebbe. Così fino a quando questo può essere dichiarato, dobbiamo prenderlo in fase di esecuzione:
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;
}
fonte
2016-03-10 19:14:36
Questa non è una risposta diretta alla sua domanda, ma per chi vuole per creare in modo conciso un oggetto funzione con proprietà, ed è OK con il cast, l'operatore [Object-Spread] (https://blog.mariusschulz.com/2016/12/23/typescript-2-1-object-rest-and -spread) sembra fare il trucco: 'var f: {(): any; someValue: numero; } = <{(): any; someValue: numero; }> { ... (() => "Ciao"), someValue: 3 }; '. – Jonathan