テーブルをTypeScript で実装する時、ヘッダ列の名称とボディ列の名称を合わせたくて、
型定義方法に悩んだので、その時のことを残しておく。
やりたいこと
- 以下のようなテーブルを作りたい。
- ヘッダ列、ボディ列どちらも型が決まっていないため、ヘッダ列の名称しか、ボディ列で使えないようにしたい
Name | TelNumber |
Test Taro | 03-1111-2222 |
Test Jiro | 03-3333-2222 |
具体的には、以下のような header に定義したkey名以外は、itemsで使えないようにしたい
const tableData = {
header: [
{ key: "name", name: "Name" },
{ key: "tel", name: "TelNumber" },
],
items: [
{ id: "1", name: "Test Taro", tel: "03-1111-2222" },
{ id: "1", name: "Test Jiro", tel: "03-3333-2222" }, // ← OK
{ id: "1", fullname: "Test Jiro", telephone: "03-3333-2222" }, // NG
],
};
結論
以下の定義で実現できた。
{
[K in Header["key"]]: string;
}
以下のような実装にすることで、item の key を header の key に限定させることができた。
type Header = {
key: string;
name: string;
};
type Item = { id: string } & {
[K in Header["key"]]: string;
};
type TableData = {
header: Header[];
items: Item[];
};
const tableData: TableData = {
header: [
{ key: "name", name: "Name" },
{ key: "tel", name: "TelNumber" },
],
items: [
{ id: "1", name: "Test Taro", tel: "03-1111-2222" },
{ id: "1", name: "Test Jiro", tel: "03-3333-2222" }, // ← OK
{ id: "1", fullname: "Test Jiro", telephone: "03-3333-2222" }, // NG
],
};