6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年4月1日 りあクト! 第4章 TypeScriptで型をご安全に 4-5 さらに高度な型表現(p.186~)

keyof演算子

通常の式では使えず、型コンテキストのみで用いられる演算子です。オブジェクトの各キーを列挙した共用体型になります。

const permissions = {
  r: 0b0100,
  w: 0b010,
  x: 0b001,
};

// typeof permissionsで、オブジェクトの型が取得できます。
// さらにkeyofを使うことで、オブジェクトの型のキーを抜き出して、共用体型を作ります。
type PermsChar = keyof typeof permissions;

// 0b0100,0b010, 0b001は、2進数です。
// インデックスアクセス演算子は型に対して使用します。
// 下のconstで宣言したpermissions1は変数です
// typeofでオブジェクトの型を抽出して、その型に対して、インデックスアクセス演算子を使っています。
const permissions1 = {
  r: 0b0100 as const,
  w: 0b010 as const,
  x: 0b001 as const,
};

type PermsChar1 = keyof typeof permissions1; 
// =>  "r" | "w" | "x"
type PermsProp = typeof permissions1['x'];
// => type PermsProp = 1
type PermsNum = typeof permissions1[PermsChar1];
// => type PermsNum = 4 | 2 | 1

配列の要素から型を作る

const species = ['a', 'b', 'c'] as const;

// インデックス番号で欲しい値を取得できます。
type Species = typeof species[0]; // "a"
type Species = typeof species[1]; // "b"
// 全てを取得するにはnumberを指定します。
type Species = typeof species[number]; 
// "a" | "b" | "c"
  • as constをつけない場合はstring[]の型として型推論されます。
  • 配列のインデックス番号を指定することで該当する要素のリテラル型を抽出出来ます。
  • インデックスの代わりにnumberを使うことで全ての要素の型を取り出すことが出来ます。

オブジェクトのValueの型を抽出する

const permissions = {
  r: 0b100 as const,
  w: 0b010 as const,
  x: 0b001 as const
}

type Perms = typeof permissions;
// => type Perms = {
//      r: 4;
//      w: 2;
//      x: 1;
//    }

// 型を関数のように扱う
type ValueOf<T> = T[keyof T];

type PermsNum1 = ValueOf<Perms>; 
// => 4 | 2 | 1 

type PermsChar = keyof Perms 
// => "r" | "w" | "x"

type PermsNum2 = typeof permissions[PermsChar]; 
// => 4 | 2 | 1
  • typeof permissionsでのオブジェクト全体の型を抽出します。
  • T[key of T]でobj[keyof T]でobj[インデックス番号]といった記法になり、オブジェクトのバリューを取得できます。

参考

りあクト! 【Ⅰ. 言語・環境編】 p.188~