【TypeScript入門】インデックス・シグネチャーの使い方を解説

どうもフロントエンドエンジニアのまさぴょんです!

今回はTypeScriptのインデックス・シグネチャー(Index-Signature)について解説します。

インデックス・シグネチャー(Index-Signature)とは?

TypeScript初学者の強い味方『サバイバルTypeScript』によると次のように説明されています。

TypeScriptで、オブジェクトのフィールド名をあえて指定せず、プロパティのみを指定したい場合があります。

そのときに使えるのがこのインデックス型(index signature)です。

たとえば、プロパティがすべてnumber型であるオブジェクトは次のように型注釈します。

let obj: {

[K: string]: number;

};

フィールド名の表現部分が[K: string]です。

このKの部分は型変数です。

任意の型変数名にできます。

Kkeyにするのが一般的です。

stringの部分はフィールド名の型を表します。

インデックス型のフィールド名の型はstringnumbersymbolのみが指定できます。

引用元: 『サバイバルTypeScript』インデックス型 (index signature)

つまり、Index-Signatureとは、Object型の「key名を変数化」できる記法だと言うことです。

let obj { [ key名: string ]: number };

と記述すれば、このobj(Object型)の「key名は変数化」(型変数)されており、string型なら自由に設定することができるようになっています。

このようなkey名を変数化することで、汎用的に使い回すことができます。

Index-Signatureで使える型は、今のところ、string, number, symbol 型のいずれかなので、使用する際はその点に注意する必要があります。

サンプルコード

それでは、より実務に近いSample-Codeを掲載したので、「TypeScript Playground」などを使って実行してみてください。

// < 型定義 > の領域展開 ----------------------------------------------------------------------------------------
interface ItemInfo { // 1. ItemInfo: 商品の基本情報
    id: number;
    name: string;
    price: number;
    stock: number;
    enableBuyFlag: boolean;  // 購入可能Flag
    stockLimitFlag: boolean; // 在庫が少なくなったら発注するようにSwitchされるFlag
}

// Index-Signature
interface CartItemObj { // 2. CartItemObj: カートに入る商品
    [key: string]: ItemInfo; //  key名は、string型なら何が入ってもOK!
}

interface CartInfo { // 3. CartInfo: カートの情報
    userId: number;
    userName: string;
    cartItem: CartItemObj[];
    address: string;
    telephone: string;
}
// -------------------------------------------------------------------------------------------------------------

const cart: CartInfo = { // 1. カート
    userId: 1,
    userName: "ロボ玉",
    cartItem: [],
    address: "グンマー帝国",
    telephone: "080-1234-5678"
};

// 2. 商品リスト
const itemList = ["apple", "greep", "mikan", "orange", "magoro", "momo", "robotama"] as const;

const apple: ItemInfo = { // 3. 商品詳細 Ver.apple
    id: 1,
    name: "apple",
    price: 100,
    stock: 12,
    enableBuyFlag: true,
    stockLimitFlag: false,
};

const greep: ItemInfo = { // 4. 商品詳細 Ver.greep
    id: 2,
    name: "greep",
    price: 200,
    stock: 7,
    enableBuyFlag: true,
    stockLimitFlag: false,
};

const addCart = (item: ItemInfo): void => { // 5. カートに追加する関数
    for(const itemName of itemList){
        if(itemName == item.name) {
            console.log(item.name, ": 登録・商品");
            const key = item.name;
            cart.cartItem.push({ [key]: item }); // ブラケット記法でkey名に変数を埋め込む
        }
    };
    
};

addCart(apple);
addCart(greep);

console.log(cart);

// < 出力結果 >
// {
//   "userId": 1,
//   "userName": "ロボ玉",
//   "cartItem": [
//     {
//       "apple": {
//         "id": 1,
//         "name": "apple",
//         "price": 100,
//         "stock": 12,
//         "enableBuyFlag": true,
//         "stockLimitFlag": false
//       }
//     },
//     {
//       "greep": {
//         "id": 2,
//         "name": "greep",
//         "price": 200,
//         "stock": 7,
//         "enableBuyFlag": true,
//         "stockLimitFlag": false
//       }
//     }
//   ],
//   "address": "グンマー帝国",
//   "telephone": "080-1234-5678"
// } 

簡単に説明すると、「2. CartItemObj: カートに入る商品」の型定義でIndex-Signatureを使用しており、「3. CartInfo: カートの情報」では「cartItem」というkey名にCartItemObjの配列を定義しています。

そして、実際の処理BlockではitemListの商品名をIndex-Signatureの型変数(key名)に使って、商品情報(ItemInfo)と紐づけています。

このように使っていくと実務でも役立つこと間違いなしなので、活用してみてください。

まとめ

  1. Index-Signatureは、key名を変数(型変数)として定義できる。

TypeScript書籍

参考・引用

1. インデックス型 (index signature)

最近の投稿