更新された回答:を介して交差タイプが追加されたため、&
2つの推定タイプをその場で「マージ」することができます。
これは、あるオブジェクトのプロパティを読み取り、from
それらをオブジェクトにコピーする一般的なヘルパーです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
型に制約されているFoo
ため、の結果はmerge
完全である必要があることに注意してください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;
}
var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };
。