👀

型演算子【個人学習まとめ】

2025/04/09に公開

型演算子

keyof

keyof演算子は指定されたオブジェクト型からプロパティのキーを抽出し、それらを結合したユニオン型を生成することができます。
keyof 演算子

interface Person {
  name: string;
  age: number;
  hobbies: string[];
}

type PersonKeys = keyof Person;
// name | age | hobbies 型

上記ではPersonインターフェイスに対してkeyof演算子を使用しています。
これにより、Person型のプロパティキーであるnameagehobbiesをリテラル型のユニオンとしてPersonKyes型に抽出することが可能です。オブジェクトのプロパティ名を安全に参照することができますね。
keyof演算子を使用せずに、次のように宣言しても同じ意味になります。

type PersonKeys = "name" | "age" | "hobbies";

typeof演算子を使って、オブジェクトの特定のプロパティにアクセスするコードを使って使用例を確認してみましょう。

console.log(`新任の先生の名前は、${getProperty(teacher, "name")} です。`);
→ 新任の先生の名前は、○○先生 です。

関数getPropertyは引数に

  • Person型のオブジェクト
  • オブジェクトのプロパティ名

を必要とします。
戻り値は、第 2 引数に指定されたプロパティの値を返却します。
第 2 引数にkeyof演算子を使用することによって、Person型に定義されているプロパティのキーのみが引数に指定することができます。
Person型に存在しないプロパティのキーaddressを指定するとエラーが発生します。

console.log(`住所は、${getProperty(teacher, "address")} です。`);
→ 型 '"address"' の引数を型 'keyof Person' のパラメーターに割り当てることはできません。

仮に関数getPropertyの第 2 引数を単純なstring型だったとしましょう。
この場合、存在しないプロパティのキーaddressが渡されたと気が付かずに、コードを実行してからエラーが発生する可能性があります。
これを未然に防ぐためにも、keyof演算子を利用することによって、関数getPropertyに渡された引数がPerson型かつ、実際に存在するプロパティ名であることを証明でき、型が安全であることが保たれます。

typeof

これまでの学習で何度かtypeof演算子が出てきました。それは JavaScript のtypeof演算子でした。
TypeScript には独自のtypeof演算子が存在します。
JavaScirpt のtypeof演算子と TypeScript 独自のtypeof演算子の違いを確認していきましょう。

JavaScript の typeof 演算子

指定した値の型を調べることができます。
こちらの記事では型の絞り込みをするためにtypeof演算子を使用しました。

console.log(typeof true);boolean
console.log(typeof 1);number
console.log(typeof "こんにちは!");string
console.log(typeof [1, 2, 3]);
→ object
console.log(typeof { a: 1, b: 2 });
→ object

TypeScript の typeof 演算子

一方、TypeScript 独自のtypeof演算子は変数から型を抽出し、型情報を返却する演算子です。
抽出した型情報は新しい変数の型注釈や関数の引数として利用することができます。

const book = {
  title: "○○の教科書",
  price: 1000,
  publicationForm: ["紙", "電子", "読み上げ"],
};

type BookType = typeof book;

上記では、変数bookからtypeof演算子を使って、変数bookの型情報を取得し型BookTypeを作成しています。
この作成した型BookTypeを関数の引数の型情報として利用することもできます。

function getBookInfo(info: BookType) {
  console.log(`本のタイトルは「${info.title}」です。`);
  → 本のタイトルは「○○の教科書」です。
  console.log(`値段は「${info.price}」円です。`);
  → 値段は「1000」円です。
  console.log(`発行形態は「${info.publicationForm}」です。`);
  → 発行形態は「紙,電子,読み上げ」です。
}

getBookInfo(book);

keyof と typeof の組み合わせ

keyof演算子とtypeof演算子を組み合わせることによって、指定されたオブジェクトのキーの型情報を抽出することができます。

const student = {
  no: 123456789,
  name: "テスト 太郎",
  club: "野球",
};

function getStudentDetail(key: keyof typeof student) {
  return student[key];
}

console.log(getStudentDetail("name"));
→ テスト 太郎

上記の例では変数studentオブジェクトから型情報を作成し、関数getStudentDetailの引数keyの型情報として利用しています。

変数studentオブジェクトに存在しないプロパティを、関数getStudentDetailに指定しようとするとエラーとなります。

getStudentDetail("gakunen")
→ 型 '"gakunen"' の引数を型 '"no" | "name" | "club"' のパラメーターに割り当てることはできません。

これにより、関数getStudentDetail内では変数studentオブジェクトに存在しないプロパティにアクセスすることはできず、タイプミスなどを防ぐことができます。

keyof演算子とtypeof演算子を組み合わせることによって、宣言されたオブジェクトから動的に取得することができます。

Discussion