更新的答案:因爲通過&
的加分交叉點的類型,就可以「合併」兩種推斷類型的飛行。
這裏有一個一般的幫手了一個對象onto
讀一些對象from
,並將它們複製的特性。它返回相同的對象onto
但一個新類型,包括套房產,所以正確描述運行時行爲:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
這種低級別的幫手也仍然執行一個類型的斷言,但它是類型 - 設計安全。有了這個幫手的地方,我們有一個運營商,我們可以使用全型安全解決OP的問題:
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。請注意,我們將foo
限制爲Foo
類型,因此merge
的結果必須是完整的Foo
。因此,如果您將bar
重命名爲bad
,那麼您會收到類型錯誤。
NB還有這裏一個類型孔,但是。 TypeScript沒有提供一種將類型參數限制爲「不是函數」的方法。所以你可能會感到困惑,並將你的函數作爲merge
的第二個參數傳遞,那就行不通了。所以,直到可以聲明,我們必須抓住它在運行時:
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;
}
這不是直接回答你的問題,但誰想要使用屬性簡潔地構建一個函數對象,並且可以通過強制轉換,[Object-Spread運算符](https://blog.mariusschulz.com/2016/12/23/typescript-2-1-object-rest-and -spread)似乎可以做到這一點:'var f:{():any; someValue:number; } = <{():any; someValue:number; }({} =>「你好」), someValue:3 };'。 – Jonathan