1. ホーム
  2. typescript

[解決済み] 他のプロパティを使用できる TypeScript インターフェース

2023-01-06 06:03:56

質問

要約すると、いくつかの基本的なプロパティを宣言し、追加のプロパティを制限しないインターフェイスを持つことは可能でしょうか?これは、私の現在の状況です。

私は フラックスパターン を使っています。

class Dispatcher<TPayload> {
    dispatch(arg:TPayload):void { }
}

次に、このように独自のペイロード型を持つディスパッチャを作成します。

interface ActionPayload {
    actionType: string
}

const dispatcher = new Dispatcher<ActionPayload>();

ここで、いくつかの追加データを含むペイロードをディスパッチするアクションコードがありますが ActionPayload インターフェースでは actionType . つまり、このコードです。

interface SomePayload extends ActionPayload {
    someOtherData: any
}

class SomeActions {
    doSomething():void {
        dispatcher.dispatch({
            actionType: "hello",
            someOtherData: {}
        })
    }
}

コンパイルエラーになるのは someOtherData とは一致しないので ActionPayload インターフェースと一致しません。問題は、多くの異なる "action" クラスが同じディスパッチャを再利用することで、それが someOtherData であるのに対し、ここでは anotherKindOfData といった具合です。今のところ、これに対応するために私ができるのは new Dispatcher<any>() を使うしかないでしょう。なぜなら、異なるアクションがディスパッチされるからです。すべてのアクションは、ベースとなる ActionPayload のような型に制約をかけられるといいなと思いました。 new Dispatcher<extends ActionPayload>() のような型拘束ができればと思っています。そのようなことは可能でしょうか?

どのように解決するのですか?

もし、あなたが ActionPayload に他のプロパティを受け入れさせたい場合は、インデクサを追加することができます。

interface ActionPayload {
    actionType: string;

    // Keys can be strings, numbers, or symbols.
    // If you know it to be strings only, you can also restrict it to that.
    // For the value you can use any or unknown, 
    // with unknown being the more defensive approach.
    [x: string | number | symbol]: unknown;
}

参照 https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#strict-object-literal-assignment-checking