0

TP1のキーをkeyofキーワードで指定したキーを特定のタイプのプロパティに限定する制約を作成する必要があります。 builder.setMetadataメソッドを使用する場合、最初のパラメータは文字列 "configure"を有効な値として受け入れるべきではありません(fooと他のキーはFoo<something>として受け入れる必要があります)。私は自分で解決策を見つけようとしましたが、少し失われて3時間以上続いています。以下は作業コードです:ルックアップタイプの一部である制限キー

interface Foo<T> {}; 

class Test { prop: string; } 

class Builder<T> { 
    public setMetadata<TP1 extends keyof this, TP2 extends keyof this[TP1]>(prop: TP1, propOfProp: TP2) { 
     // ... 
    } 
} 

class Bar { 
    foo: Foo<Test>; 

    configure(builder: Builder<Bar>) { 
     builder.setMetadata("", ""); // only "foo" should be accepted value in the first argument, "configure" shouldn't be in the list 
    } 
} 

答えて

0

どうやってですか?別々にsetMetadataの第二のparamタイプkeyof

  • 移動FOOを使用していないsetMetadataのタイプ
    • 使用T代わりのthis

      class Builder<T> { 
          public setMetadata<TP1 extends keyof T, TP2 extends T[TP1]>(prop: TP1, propOfProp: TP2) { 
          // ... 
          } 
      } 
      
      class BarData { 
          foo: Foo<Test>; 
      } 
      
      class Bar extends BarData { 
          configure(builder: Builder<BarData>) { 
          // ... 
          } 
      } 
      

      私はいくつかの場所で変更を加えましたクラス

  • +0

    ご回答ありがとうございます。継承の使用は残念ながらオプションではありません。 'configure'メソッドは、fooプロパティを保持するクラスの親クラスになるクラスで定義されます。これはクライアント側のAPIの一部であり、できるだけシンプルにしたいと考えています。 – Tom

    +0

    あなたは実際に 'Foo 'を空にしようとしていますか?それをsetMetadataの型パラメータを制約するためだけに使うことを望んでいますか?これはTypeScriptの構造型の性質のため動作しません。空のインターフェイスは何も受け付けません。これを行うには、特別なマーカーフィールドを持つクラスインスタンスまたはコンテナオブジェクトのフィールドにボックスを作成する必要があります。あるいは、あなたはデコレータで何かをすることができます(私はそれらを使用していないので、コメントすることはできません)。 – dbandstra

    +0

    あなたは正しいです。私は別の方法(機能)でそれを解決し、私自身の答えを参照してください。残念なことに、デコレータはこの問題を解決しません。あなたの時間と努力に感謝します。 – Tom

    0

    解決済みusi機能:

    function createInstance<T extends Function & { [P in keyof TSchema]: Foo<any> }>(schema: T, configure: (builder: Builder<T["prototype"]>) => void): any { 
        // ... 
    } 
    
    関連する問題