Kを使用する場合のT [K]のタイプの絞り込みは、Tのキーを拡張します[重複]

Nov 21 2020

私は次のようなインターフェースを定義しようとしています:

  • 1つのプロパティはジェネリック型のキーです
  • 別のプロパティは、他のプロパティのそのキーに関連付けられているのタイプに依存しています

私が得ることができる最も近いものは、TypescriptがT [K]をTのすべての値の共用体型に解決することです。しかし、Kが既知の文字列リテラルである場合、それをさらに絞り込む方法があるはずです。

これが私がやろうとしていることの例です。

テスト

interface Person {
    age: number;
    name: string;
}

interface ColumnDef<T, K extends keyof T> {
    key: K;
    renderData: (value: T[K]) => void;
}

interface Report<T> {
    columns: ColumnDef<T, keyof T>[];
}

const report: Report<Person> = {
    columns: [
        {
            key: "age", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // ideally value should be "number" here, but it is "string|number"
            }
        },
        {
            key: "name", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // ideally value should be "string" here, but it is "string|number"
            }
        },
    ]
}

回答

1 CraigC Nov 21 2020 at 03:20

キャプテン・ヨサリアンからリンクされた関連する質問に続いて、私はこの回答を使用してタイプを絞り込むことができました。

それが誰かをさらに助ける場合に備えて、これが私の例のケースにそれをどのように適用したかです。

interface Person {
    age: number;
    name: string;
}

type ColumnDef<T> = {
    [K in keyof T]-?: BaseColumnDef<T, K>
  }[keyof T]


interface BaseColumnDef<T, K extends keyof T> {
    key: K;
    renderData: (value: T[K]) => void;
}

interface Report<T> {
    columns: ColumnDef<T>[];
}

const report: Report<Person> = {
    columns: [
        {
            key: "age", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "number"
            }
        },
        {
            key: "name", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "string"
            }
        },
    ]
}