更新された回答: を介した交差タイプの追加以来、&
その場で 2 つの推論されたタイプを「マージ」することが可能です。
これは、いくつかのオブジェクトのプロパティを読み取り、from
それらを object にコピーする一般的なヘルパーですonto
。同じオブジェクトを返します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}`)
}
}
);
TypeScript Playground で試してみるには、ここをクリックしてください。foo
を typeに制約しているFoo
ため、 の結果はmerge
complete でなければならないことに注意してくださいFoo
。bar
そのため、名前を に変更するとbad
、型エラーが発生します。
注: ただし、ここにはまだ 1 つのタイプの穴があります。TypeScript は、型パラメーターを「関数ではない」ように制約する方法を提供しません。そのため、混乱して関数を の 2 番目の引数として渡すことができますが、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;
}