この質問は一日中、私を悩ませてきたので、私はそれを周りに演奏し、私が持っていないながら、解決策(悲しいことに)、私はあなたの正確なユースケースに応じて、あなたに役立つかもしれないし、役に立たないかもしれないいくつかの面白い振る舞いを発見しました。
TL; DR:Fooの特定のケースでは、一般的ではないが、あなたが望むものを得ることができます。それはタイスクリプトの部分に限界があるようです。
だから、最初、一緒にISetEventArgs
のフィールドと値をバインドすることができます:
interface ISetEventArgs<T, K extends keyof T> {
field: K;
value: T[K];
}
は今、問題がタイプです:
ISetEventArgs<Foo, "id"|"name|"birth">
:
ISetEventArgs<Foo, keyof Foo>
はに解決
私たちはそれになりたい:第二の場合には、我々はtypescriptですの判別組合の機能を利用することができますので
ISetEventArgs<Foo, "id"> | ISetEventArgs<Foo, "name"> | ISetEventArgs<Foo, "birth">
。これらは意味的には同じように見えますが、タイプスクリプトは2番目のケースのみを絞り込みます。だから私たちはそれをその形にするためにいくつかのタイプの偽善をする必要があります。
そこで、我々は、タイプ定義する場合:
type FooArgs = {[K in keyof Foo]: ISetEventArgs<Foo, K>}[keyof Foo]
をし、我々はそれがどのようなタイプで動作するように、このパターンを拡張しようとする場合には、悲しいことに、私たちが望むものに解決...しかし:
type GenericArgs<T> = {[K in keyof T]: ISetEventArgs<T, K>}[keyof T];
type GenricFooArgs = GenericArgs<Foo>;
突然、GenericFooArgs
は、上記の最初のタイプに解決されます。 FooArgs
を手動で宣言する理由が、GenericArgs<Foo>
を使用する方法とは違うのは分かりません。
したがって、ISetEventArgs<T>
の代わりにFooArgs
を使用すると、ハンドラを実装するときに必要なものが得られます。しかし...あなたはbind
の一般的な能力を失ってしまったので、結局は価値のある取引ではないかもしれません。
これはあなたに役立つかもしれませんhttps://stackoverflow.com/questions/40249906/using-a-generic-type-argument-with-typeof-t –